Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs

This commit is contained in:
2026-05-29 20:52:26 -05:00
parent d26e357448
commit abea319ea0
110 changed files with 25714 additions and 31014 deletions
+145 -144
View File
@@ -2,163 +2,164 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool InterperterThread::Add(std::shared_ptr<GC> gc)
{
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
GCList ls(gc);
auto right = cse.back()->Pop(ls);
auto left = cse.back()->Pop(ls);
bool InterperterThread::Add(std::shared_ptr<GC> gc) {
std::vector<CallStackEntry *> &cse = this->call_stack_entries;
GCList ls(gc);
auto right = cse.back()->Pop(ls);
auto left = cse.back()->Pop(ls);
if (std::holds_alternative<std::string>(left) &&
std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right)) {
cse.back()->Push(
gc, std::get<std::string>(left) +
std::get<Tesses::Framework::Filesystem::VFSPath>(right));
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<char>(right)) {
cse.back()->Push(gc,
(char)(std::get<char>(left) + std::get<char>(right)));
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<char>(right)) {
cse.back()->Push(
gc, (char)(std::get<int64_t>(left) + std::get<char>(right)));
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(
gc, (char)(std::get<char>(left) + std::get<int64_t>(right)));
} else if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
left) &&
std::holds_alternative<std::string>(right)) {
cse.back()->Push(
gc, std::get<Tesses::Framework::Filesystem::VFSPath>(left) +
std::get<std::string>(right));
if(std::holds_alternative<std::string>(left) && std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right))
{
cse.back()->Push(gc,std::get<std::string>(left) + std::get<Tesses::Framework::Filesystem::VFSPath>(right));
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right))
{
cse.back()->Push(gc,(char)(std::get<char>(left) + std::get<char>(right)));
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right))
{
cse.back()->Push(gc, (char)(std::get<int64_t>(left) + std::get<char>(right)));
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc, (char)(std::get<char>(left) + std::get<int64_t>(right)));
}
else if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(left) && std::holds_alternative<std::string>(right))
{
cse.back()->Push(gc,std::get<Tesses::Framework::Filesystem::VFSPath>(left) + std::get<std::string>(right));
}
}
else if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(left) && std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right))
{
cse.back()->Push(gc,std::get<Tesses::Framework::Filesystem::VFSPath>(left) + std::get<Tesses::Framework::Filesystem::VFSPath>(right));
}
else if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
left) &&
std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
right)) {
cse.back()->Push(
gc, std::get<Tesses::Framework::Filesystem::VFSPath>(left) +
std::get<Tesses::Framework::Filesystem::VFSPath>(right));
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc,std::get<int64_t>(left) + std::get<int64_t>(right));
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<double>(right))
{
cse.back()->Push(gc,std::get<double>(left) + std::get<double>(right));
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc,std::get<double>(left) + std::get<int64_t>(right));
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right))
{
cse.back()->Push(gc,std::get<int64_t>(left) + std::get<double>(right));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) + (*r)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
}
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<std::string>(right))
{
std::string str={};
str.append(std::get<std::string>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc,str);
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<std::string>(right))
{
std::string str={};
str.push_back(std::get<char>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc,str);
}
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<char>(right))
{
std::string str={};
str.append(std::get<std::string>(left));
str.push_back(std::get<char>(right));
cse.back()->Push(gc,str);
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
if(cls != nullptr)
{
gc->BarrierBegin();
auto obj=cls->GetValue(cse.back()->callable->className,"operator+");
gc->BarrierEnd();
TClosure* clos;
TCallable* callable;
if(GetObjectHeap(obj,clos))
{
this->AddCallStackEntry(ls,clos,{right});
return true;
}
else if(GetObjectHeap(obj,callable))
{
cse.back()->Push(gc,callable->Call(ls,{right}));
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
else if(natObj != nullptr)
{
cse.back()->Push(gc, natObj->CallMethod(ls,"operator+",{right}));
}
else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(gc,
std::get<int64_t>(left) + std::get<int64_t>(right));
}
else if (std::holds_alternative<double>(left) &&
std::holds_alternative<double>(right)) {
cse.back()->Push(gc, std::get<double>(left) + std::get<double>(right));
} else if (std::holds_alternative<double>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(gc, std::get<double>(left) + std::get<int64_t>(right));
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<double>(right)) {
cse.back()->Push(gc, std::get<int64_t>(left) + std::get<double>(right));
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) &&
std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) {
auto &l =
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto &r =
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(
gc,
std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) + (*r)));
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) &&
std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) {
auto &l =
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto &r =
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(
gc,
std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) &&
std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)) {
auto &l =
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto &r =
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(
gc,
std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
} else if (std::holds_alternative<std::string>(left) &&
std::holds_alternative<std::string>(right)) {
std::string str = {};
str.append(std::get<std::string>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc, str);
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<std::string>(right)) {
std::string str = {};
str.push_back(std::get<char>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc, str);
} else if (std::holds_alternative<std::string>(left) &&
std::holds_alternative<char>(right)) {
std::string str = {};
str.append(std::get<std::string>(left));
str.push_back(std::get<char>(right));
cse.back()->Push(gc, str);
} else if (std::holds_alternative<THeapObjectHolder>(left)) {
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary *>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject *>(obj);
if (cls != nullptr) {
gc->BarrierBegin();
auto obj =
cls->GetValue(cse.back()->callable->className, "operator+");
gc->BarrierEnd();
TClosure *clos;
TCallable *callable;
if (GetObjectHeap(obj, clos)) {
this->AddCallStackEntry(ls, clos, {right});
return true;
} else if (GetObjectHeap(obj, callable)) {
cse.back()->Push(gc, callable->Call(ls, {right}));
return false;
}
else if(dict != nullptr)
{
gc->BarrierBegin();
TObject fn = dict->GetValue("operator+");
gc->BarrierEnd();
return InvokeTwo(ls,fn,left,right);
}
else if(dynDict != nullptr)
{
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator+",{right}));
return false;
}
else
{
cse.back()->Push(gc, Undefined());
}
}
else
{
cse.back()->Push(gc, Undefined());
return false;
} else if (natObj != nullptr) {
cse.back()->Push(gc, natObj->CallMethod(ls, "operator+", {right}));
return false;
} else if (dict != nullptr) {
gc->BarrierBegin();
TObject fn = dict->GetValue("operator+");
gc->BarrierEnd();
return InvokeTwo(ls, fn, left, right);
} else if (dynDict != nullptr) {
cse.back()->Push(gc, dynDict->CallMethod(ls, "operator+", {right}));
return false;
} else {
cse.back()->Push(gc, Undefined());
}
return false;
} else {
cse.back()->Push(gc, Undefined());
}
}
return false;
}
} // namespace Tesses::CrossLang
+160 -196
View File
@@ -2,235 +2,199 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right)
{
GCList ls(gc);
if(std::holds_alternative<std::nullptr_t>(left) && std::holds_alternative<std::nullptr_t>(right))
{
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right) {
GCList ls(gc);
if (std::holds_alternative<std::nullptr_t>(left) &&
std::holds_alternative<std::nullptr_t>(right)) {
return true;
}
return true;
}
else if(std::holds_alternative<Undefined>(left) && std::holds_alternative<Undefined>(right))
{
return true;
}
else if (std::holds_alternative<Undefined>(left) &&
std::holds_alternative<Undefined>(right)) {
return true;
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<int64_t>(right))
{
return std::get<int64_t>(left) == std::get<int64_t>(right);
}
else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<int64_t>(right)) {
return std::get<int64_t>(left) == std::get<int64_t>(right);
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<double>(right))
{
return std::get<double>(left) == std::get<double>(right);
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right))
{
return std::get<double>(left) == std::get<int64_t>(right);
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right))
{
return std::get<int64_t>(left) == std::get<double>(right);
}
else if (std::holds_alternative<double>(left) &&
std::holds_alternative<double>(right)) {
return std::get<double>(left) == std::get<double>(right);
} else if (std::holds_alternative<double>(left) &&
std::holds_alternative<int64_t>(right)) {
return std::get<double>(left) == std::get<int64_t>(right);
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<double>(right)) {
return std::get<int64_t>(left) == std::get<double>(right);
}
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<std::string>(right))
{
return std::get<std::string>(left) == std::get<std::string>(right);
}
else if (std::holds_alternative<std::string>(left) &&
std::holds_alternative<std::string>(right)) {
return std::get<std::string>(left) == std::get<std::string>(right);
}
else if(std::holds_alternative<bool>(left) && std::holds_alternative<bool>(right))
{
return std::get<bool>(left) == std::get<bool>(right);
}
else if (std::holds_alternative<bool>(left) &&
std::holds_alternative<bool>(right)) {
return std::get<bool>(left) == std::get<bool>(right);
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right))
{
return std::get<char>(left) == std::get<char>(right);
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right))
{
return std::get<char>(left) == std::get<int64_t>(right);
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right))
{
return std::get<int64_t>(left) == std::get<char>(right);
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left)->ToEpoch() == std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)->ToEpoch();
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left)->TotalSeconds() == std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)->TotalSeconds();
}
else if(std::holds_alternative<TVMVersion>(left) && std::holds_alternative<TVMVersion>(right))
{
auto lver= std::get<TVMVersion>(left);
auto rver = std::get<TVMVersion>(right);
auto r = lver.CompareTo(rver);
return r == 0;
}
else if(std::holds_alternative<Tesses::Framework::Uuid>(left) && std::holds_alternative<Tesses::Framework::Uuid>(right))
{
auto l= std::get<Tesses::Framework::Uuid>(left);
auto r = std::get<Tesses::Framework::Uuid>(right);
return l == r;
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary*>(obj);
else if (std::holds_alternative<char>(left) &&
std::holds_alternative<char>(right)) {
return std::get<char>(left) == std::get<char>(right);
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<int64_t>(right)) {
return std::get<char>(left) == std::get<int64_t>(right);
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<char>(right)) {
return std::get<int64_t>(left) == std::get<char>(right);
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) &&
std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)) {
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(
left)
->ToEpoch() ==
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(
right)
->ToEpoch();
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) &&
std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) {
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(
left)
->TotalSeconds() ==
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(
right)
->TotalSeconds();
} else if (std::holds_alternative<TVMVersion>(left) &&
std::holds_alternative<TVMVersion>(right)) {
auto lver = std::get<TVMVersion>(left);
auto rver = std::get<TVMVersion>(right);
auto r = lver.CompareTo(rver);
return r == 0;
} else if (std::holds_alternative<Tesses::Framework::Uuid>(left) &&
std::holds_alternative<Tesses::Framework::Uuid>(right)) {
auto l = std::get<Tesses::Framework::Uuid>(left);
auto r = std::get<Tesses::Framework::Uuid>(right);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto native = dynamic_cast<TNative*>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
if(cls != nullptr)
{
gc->BarrierBegin();
auto obj=cls->GetValue("","operator==");
gc->BarrierEnd();
TCallable* callable;
if(GetObjectHeap(obj,callable))
{
return ToBool(callable->Call(ls,{right}));
}
else if(std::holds_alternative<std::nullptr_t>(right)) {
return false;
}
else if(std::holds_alternative<Undefined>(right))
{
return false;
}
else if(std::holds_alternative<THeapObjectHolder>(right))
{
return cls == std::get<THeapObjectHolder>(right).obj;
}
return l == r;
} else if (std::holds_alternative<THeapObjectHolder>(left)) {
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary *>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
auto native = dynamic_cast<TNative *>(obj);
auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject *>(obj);
if (cls != nullptr) {
gc->BarrierBegin();
auto obj = cls->GetValue("", "operator==");
gc->BarrierEnd();
TCallable *callable;
if (GetObjectHeap(obj, callable)) {
return ToBool(callable->Call(ls, {right}));
} else if (std::holds_alternative<std::nullptr_t>(right)) {
return false;
} else if (std::holds_alternative<Undefined>(right)) {
return false;
} else if (std::holds_alternative<THeapObjectHolder>(right)) {
return cls == std::get<THeapObjectHolder>(right).obj;
}
else
if(natObj != nullptr)
{
return natObj->Equals(gc, right);
}
if(dict != nullptr)
{
gc->BarrierBegin();
TObject fn = dict->GetValue("operator==");
gc->BarrierEnd();
if(!std::holds_alternative<Undefined>(fn))
{
if(std::holds_alternative<THeapObjectHolder>(fn))
{
} else if (natObj != nullptr) {
return natObj->Equals(gc, right);
}
if (dict != nullptr) {
gc->BarrierBegin();
TObject fn = dict->GetValue("operator==");
gc->BarrierEnd();
if (!std::holds_alternative<Undefined>(fn)) {
if (std::holds_alternative<THeapObjectHolder>(fn)) {
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj);
if(obj != nullptr)
{
auto closure = dynamic_cast<TClosure*>(obj);
if(closure != nullptr)
{
if(!closure->closure->args.empty() && closure->closure->args[0] == "this")
{
return ToBool(obj->Call(ls,{left,right}));
}
else
{
return ToBool(obj->Call(ls,{right}));
}
auto obj = dynamic_cast<TCallable *>(
std::get<THeapObjectHolder>(fn).obj);
if (obj != nullptr) {
auto closure = dynamic_cast<TClosure *>(obj);
if (closure != nullptr) {
if (!closure->closure->args.empty() &&
closure->closure->args[0] == "this") {
return ToBool(obj->Call(ls, {left, right}));
} else {
return ToBool(obj->Call(ls, {right}));
}
else
{
return ToBool(obj->Call(ls,{right}));
}
} else {
return ToBool(obj->Call(ls, {right}));
}
else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
} else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
return dict == std::get<THeapObjectHolder>(right).obj;
}
}
else {
} else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
return false;
} else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
else if(dynDict != nullptr)
{
auto res = dynDict->CallMethod(ls,"operator==",{right});
if(!std::holds_alternative<std::nullptr_t>(res) && std::holds_alternative<Undefined>(res))
{
return ToBool(res);
}
}
else if(native != nullptr && std::holds_alternative<std::nullptr_t>(right))
{
return native->GetDestroyed();
}
if(std::holds_alternative<THeapObjectHolder>(right))
{
return obj == std::get<THeapObjectHolder>(right).obj;
}
else if(std::holds_alternative<std::nullptr_t>(right))
{
return false;
}
else if(std::holds_alternative<Undefined>(right))
{
return false;
}
else
{
return false;
}
}
else if(std::holds_alternative<std::nullptr_t>(right))
{
return false;
}
else if(std::holds_alternative<Undefined>(right))
{
return false;
}
else
{
return false;
}
return false;
else if (dynDict != nullptr) {
auto res = dynDict->CallMethod(ls, "operator==", {right});
if (!std::holds_alternative<std::nullptr_t>(res) &&
std::holds_alternative<Undefined>(res)) {
return ToBool(res);
}
} else if (native != nullptr &&
std::holds_alternative<std::nullptr_t>(right)) {
return native->GetDestroyed();
}
if (std::holds_alternative<THeapObjectHolder>(right)) {
return obj == std::get<THeapObjectHolder>(right).obj;
}
else if (std::holds_alternative<std::nullptr_t>(right)) {
return false;
} else if (std::holds_alternative<Undefined>(right)) {
return false;
} else {
return false;
}
}
}
else if (std::holds_alternative<std::nullptr_t>(right)) {
return false;
} else if (std::holds_alternative<Undefined>(right)) {
return false;
} else {
return false;
}
return false;
}
} // namespace Tesses::CrossLang
+3460 -3754
View File
File diff suppressed because it is too large Load Diff
+656 -776
View File
File diff suppressed because it is too large Load Diff
+31 -38
View File
@@ -2,53 +2,46 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool InterperterThread::InvokeMethod(GCList& ls, TObject fn, TObject instance, std::vector<TObject> args)
{
if(std::holds_alternative<THeapObjectHolder>(fn))
{
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj);
if(obj != nullptr)
{
auto closure = dynamic_cast<TClosure*>(obj);
if(closure != nullptr)
{
if(!closure->closure->args.empty() && closure->closure->args[0] == "this")
{
std::vector<TObject> args2;
args2.push_back(instance);
args2.insert(args2.end(), args.begin(),args.end());
this->AddCallStackEntry(ls,closure,args2);
}
else
{
this->AddCallStackEntry(ls,closure,args);
}
bool InterperterThread::InvokeMethod(GCList &ls, TObject fn, TObject instance,
std::vector<TObject> args) {
if (std::holds_alternative<THeapObjectHolder>(fn)) {
auto obj =
dynamic_cast<TCallable *>(std::get<THeapObjectHolder>(fn).obj);
if (obj != nullptr) {
auto closure = dynamic_cast<TClosure *>(obj);
if (closure != nullptr) {
if (!closure->closure->args.empty() &&
closure->closure->args[0] == "this") {
std::vector<TObject> args2;
args2.push_back(instance);
args2.insert(args2.end(), args.begin(), args.end());
this->AddCallStackEntry(ls, closure, args2);
} else {
this->AddCallStackEntry(ls, closure, args);
}
else
{
auto val = obj->Call(ls,args);
this->call_stack_entries.back()->Push(ls.GetGC(), val);
return false;
}
return true;
} else {
auto val = obj->Call(ls, args);
this->call_stack_entries.back()->Push(ls.GetGC(), val);
return false;
}
return true;
}
this->call_stack_entries.back()->Push(ls.GetGC(),Undefined());
return false;
}
}
this->call_stack_entries.back()->Push(ls.GetGC(), Undefined());
return false;
}
} // namespace Tesses::CrossLang
+27 -33
View File
@@ -2,46 +2,40 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool InterperterThread::InvokeTwo(GCList& ls, TObject fn, TObject left, TObject right)
{
if(std::holds_alternative<THeapObjectHolder>(fn))
{
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj);
if(obj != nullptr)
{
auto closure = dynamic_cast<TClosure*>(obj);
if(closure != nullptr)
{
if(!closure->closure->args.empty() && closure->closure->args[0] == "this")
{
this->AddCallStackEntry(ls,closure,{left,right});
}
else
{
this->AddCallStackEntry(ls,closure,{right});
}
bool InterperterThread::InvokeTwo(GCList &ls, TObject fn, TObject left,
TObject right) {
if (std::holds_alternative<THeapObjectHolder>(fn)) {
auto obj =
dynamic_cast<TCallable *>(std::get<THeapObjectHolder>(fn).obj);
if (obj != nullptr) {
auto closure = dynamic_cast<TClosure *>(obj);
if (closure != nullptr) {
if (!closure->closure->args.empty() &&
closure->closure->args[0] == "this") {
this->AddCallStackEntry(ls, closure, {left, right});
} else {
this->AddCallStackEntry(ls, closure, {right});
}
else
{
this->call_stack_entries[this->call_stack_entries.size()-1]->Push(ls.GetGC(), obj->Call(ls,{right}));
return false;
}
return true;
} else {
this->call_stack_entries[this->call_stack_entries.size() - 1]
->Push(ls.GetGC(), obj->Call(ls, {right}));
return false;
}
return true;
}
return false;
}
}
return false;
}
} // namespace Tesses::CrossLang
+297 -335
View File
@@ -2,371 +2,333 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
static void empty()
{
}
bool InterperterThread::SetField(std::shared_ptr<GC> gc)
{
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
static void empty() {}
bool InterperterThread::SetField(std::shared_ptr<GC> gc) {
std::vector<CallStackEntry *> &cse = this->call_stack_entries;
if(!cse.empty())
{
auto stk = cse.back();
GCList ls(gc);
TObject value = stk->Pop(ls);
TObject _key = stk->Pop(ls);
TObject instance = stk->Pop(ls);
if(!std::holds_alternative<std::string>(_key))
{
stk->Push(gc,Undefined());
return false;
}
if (!cse.empty()) {
auto stk = cse.back();
GCList ls(gc);
TObject value = stk->Pop(ls);
TObject _key = stk->Pop(ls);
TObject instance = stk->Pop(ls);
std::string key = std::get<std::string>(_key);
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TF_Timer_Handle>>(instance))
{
auto handle = std::get<std::shared_ptr<Tesses::Framework::TF_Timer_Handle>>(instance);
if(handle)
{
int64_t ms;
bool b;
if(key == "Enabled" && GetObject(value,b))
{
if (!std::holds_alternative<std::string>(_key)) {
stk->Push(gc, Undefined());
return false;
}
handle->SetEnabled(b);
std::string key = std::get<std::string>(_key);
if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::TF_Timer_Handle>>(
instance)) {
auto handle =
std::get<std::shared_ptr<Tesses::Framework::TF_Timer_Handle>>(
instance);
if (handle) {
int64_t ms;
bool b;
if (key == "Enabled" && GetObject(value, b)) {
cse.back()->Push(gc,b);
return false;
}
handle->SetEnabled(b);
if(key == "Interval" && GetObject(value, ms))
{
handle->SetIntervalFromMilliseconds(ms);
cse.back()->Push(gc,ms);
return false;
}
if(key == "Callback")
{
TCallable* callable;
if(GetObjectHeap(value,callable))
{
auto obj = CreateMarkedTObject(ls.GetGC(), callable);
handle->SetCallback([obj]()->void {
TCallable* callable;
if(GetObjectHeap(obj->GetObject(), callable))
{
GCList ls(obj->GetGC());
callable->Call(ls,{});
}
});
cse.back()->Push(gc, callable);
return false;
}
else
{
handle->SetCallback(empty);
cse.back()->Push(gc, nullptr);
return false;
}
}
}
cse.back()->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance))
{
auto writer = std::get<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance);
auto stringWriter = std::dynamic_pointer_cast<Tesses::Framework::TextStreams::StringWriter>(writer);
if(stringWriter != nullptr)
{
if(key == "Text")
{
if(std::holds_alternative<std::string>(value))
{
stringWriter->GetString() = std::get<std::string>(value);
}
cse.back()->Push(gc, stringWriter->GetString());
return false;
}
}
if(key == "NewLine")
{
if(std::holds_alternative<std::string>(value))
{
writer->newline = std::get<std::string>(value);
}
cse.back()->Push(gc,writer->newline);
cse.back()->Push(gc, b);
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(instance))
{
auto vfs = std::get<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(instance);
auto relative = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::RelativeFilesystem>(vfs);
if(relative)
{
if(key == "Working")
{
Tesses::Framework::Filesystem::VFSPath path;
if(GetObjectAsPath(value,path))
{
if(path.relative)
{
relative->SetWorking(path.MakeAbsolute(relative->GetWorking()));
if (key == "Interval" && GetObject(value, ms)) {
handle->SetIntervalFromMilliseconds(ms);
cse.back()->Push(gc, ms);
return false;
}
if (key == "Callback") {
TCallable *callable;
if (GetObjectHeap(value, callable)) {
auto obj = CreateMarkedTObject(ls.GetGC(), callable);
handle->SetCallback([obj]() -> void {
TCallable *callable;
if (GetObjectHeap(obj->GetObject(), callable)) {
GCList ls(obj->GetGC());
callable->Call(ls, {});
}
else {
relative->SetWorking(path);
});
cse.back()->Push(gc, callable);
return false;
} else {
handle->SetCallback(empty);
cse.back()->Push(gc, nullptr);
return false;
}
}
}
cse.back()->Push(gc, Undefined());
return false;
}
if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(
instance)) {
auto writer = std::get<
std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(
instance);
auto stringWriter = std::dynamic_pointer_cast<
Tesses::Framework::TextStreams::StringWriter>(writer);
if (stringWriter != nullptr) {
if (key == "Text") {
if (std::holds_alternative<std::string>(value)) {
stringWriter->GetString() =
std::get<std::string>(value);
}
cse.back()->Push(gc, stringWriter->GetString());
return false;
}
}
if (key == "NewLine") {
if (std::holds_alternative<std::string>(value)) {
writer->newline = std::get<std::string>(value);
}
cse.back()->Push(gc, writer->newline);
return false;
}
cse.back()->Push(gc, Undefined());
return false;
}
if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(
instance)) {
auto vfs =
std::get<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(
instance);
auto relative = std::dynamic_pointer_cast<
Tesses::Framework::Filesystem::RelativeFilesystem>(vfs);
if (relative) {
if (key == "Working") {
Tesses::Framework::Filesystem::VFSPath path;
if (GetObjectAsPath(value, path)) {
if (path.relative) {
relative->SetWorking(
path.MakeAbsolute(relative->GetWorking()));
} else {
relative->SetWorking(path);
}
}
}
}
cse.back()->Push(gc, Undefined());
return false;
}
if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Http::IHttpServer>>(
instance)) {
auto svr =
std::get<std::shared_ptr<Tesses::Framework::Http::IHttpServer>>(
instance);
auto bas = std::dynamic_pointer_cast<
Tesses::Framework::Http::BasicAuthServer>(svr);
auto cgi =
std::dynamic_pointer_cast<Tesses::Framework::Http::CGIServer>(
svr);
auto changable = std::dynamic_pointer_cast<
Tesses::Framework::Http::ChangeableServer>(svr);
if (changable != nullptr) {
if (key == "Server") {
bas->server = ToHttpServer(gc, value);
stk->Push(gc, value);
return false;
}
}
if (bas != nullptr) {
if (key == "Realm") {
bool val;
if (GetObject(value, val)) {
bas->realm = val;
stk->Push(gc, val);
return false;
}
}
if (key == "Server") {
bas->server = ToHttpServer(gc, value);
stk->Push(gc, value);
return false;
}
if (key == "Authorization") {
TCallable *val;
if (GetObjectHeap(value, val)) {
auto marked = CreateMarkedTObject(ls, val);
bas->authorization =
[marked](std::string user,
std::string password) -> bool {
GCList ls(marked->GetGC());
TCallable *callable;
if (GetObjectHeap(marked->GetObject(), callable)) {
return ToBool(
callable->Call(ls, {user, password}));
}
}
return false;
};
stk->Push(gc, val);
return false;
}
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Http::IHttpServer>>(instance))
{
auto svr = std::get<std::shared_ptr<Tesses::Framework::Http::IHttpServer>>(instance);
auto bas = std::dynamic_pointer_cast<Tesses::Framework::Http::BasicAuthServer>(svr);
auto cgi = std::dynamic_pointer_cast<Tesses::Framework::Http::CGIServer>(svr);
auto changable = std::dynamic_pointer_cast<Tesses::Framework::Http::ChangeableServer>(svr);
if(changable != nullptr)
{
if(key == "Server")
{
bas->server = ToHttpServer(gc,value);
stk->Push(gc,value);
if (cgi != nullptr) {
if (key == "WorkingDirectory") {
Tesses::Framework::Filesystem::VFSPath path;
if (GetObjectAsPath(value, path)) {
cgi->workingDirectory = path;
stk->Push(gc, path);
return false;
} else {
cgi->workingDirectory = std::nullopt;
stk->Push(gc, nullptr);
return false;
}
}
if(bas != nullptr)
{
if(key == "Realm")
{
bool val;
if(GetObject(value,val))
{
bas->realm = val;
stk->Push(gc,val );
return false;
}
}
if(key == "Server")
{
bas->server = ToHttpServer(gc,value);
stk->Push(gc,value);
if (key == "DocumentRoot") {
Tesses::Framework::Filesystem::VFSPath path;
if (GetObjectAsPath(value, path)) {
cgi->document_root = path;
stk->Push(gc, path);
return false;
} else {
cgi->document_root = std::nullopt;
stk->Push(gc, nullptr);
return false;
}
if(key == "Authorization")
{
TCallable* val;
if(GetObjectHeap(value,val))
{
auto marked= CreateMarkedTObject(ls, val);
bas->authorization = [marked](std::string user,std::string password)->bool {
GCList ls(marked->GetGC());
TCallable* callable;
if(GetObjectHeap(marked->GetObject(), callable))
{
return ToBool(callable->Call(ls,{user,password}));
}
return false;
};
stk->Push(gc,val);
return false;
}
}
if (key == "AdminEmail") {
std::string str;
if (GetObject(value, str)) {
cgi->adminEmail = str;
stk->Push(gc, str);
return false;
} else {
cgi->adminEmail = std::nullopt;
stk->Push(gc, nullptr);
return false;
}
}
if(cgi != nullptr)
{
if(key == "WorkingDirectory")
{
Tesses::Framework::Filesystem::VFSPath path;
if(GetObjectAsPath(value,path))
{
cgi->workingDirectory = path;
stk->Push(gc,path);
return false;
}
else {
cgi->workingDirectory = std::nullopt;
stk->Push(gc,nullptr);
return false;
}
}
if(key == "DocumentRoot")
{
Tesses::Framework::Filesystem::VFSPath path;
if(GetObjectAsPath(value,path))
{
cgi->document_root= path;
stk->Push(gc,path);
return false;
}
else {
cgi->document_root= std::nullopt;
stk->Push(gc,nullptr);
return false;
}
}
if(key == "AdminEmail")
{
std::string str;
if(GetObject(value,str))
{
cgi->adminEmail = str;
stk->Push(gc,str);
return false;
}
else {
cgi->adminEmail= std::nullopt;
stk->Push(gc,nullptr);
return false;
}
}
}
stk->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance))
{
auto strm = std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance);
auto netStrm = std::dynamic_pointer_cast<Tesses::Framework::Streams::NetworkStream>(strm);
if(netStrm != nullptr)
{
int64_t n0;
bool bc;
if(key == "Broadcast" && GetObject(value,bc))
netStrm->SetBroadcast(bc);
if(key == "NoDelay" && GetObject(value,bc))
netStrm->SetNoDelay(bc);
if(key == "ReuseAddress" && GetObject(value,bc))
netStrm->SetReuseAddress(bc);
if(key == "ReusePort" && GetObject(value,bc))
netStrm->SetReusePort(bc);
if(key == "MulticastTTL" && GetObject(value,n0))
netStrm->SetMulticastTTL((uint8_t)n0);
}
stk->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<THeapObjectHolder>(instance))
{
auto obj = std::get<THeapObjectHolder>(instance).obj;
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
if(cls != nullptr)
{
gc->BarrierBegin();
auto obj=cls->GetValue(cse.back()->callable->className,"set"+key);
gc->BarrierEnd();
TClosure* clos;
TCallable* callable;
if(GetObjectHeap(obj,clos))
{
this->AddCallStackEntry(ls,clos,{value});
return true;
}
else if(GetObjectHeap(obj,callable))
{
cse.back()->Push(gc,callable->Call(ls,{value}));
return false;
}
gc->BarrierBegin();
cls->SetValue(cse.back()->callable->className,key,value);
gc->BarrierEnd();
cse.back()->Push(gc,value);
return false;
}
else
if(natObj != nullptr)
{
cse.back()->Push(gc,natObj->CallMethod(ls,"set"+key,{value}));
return false;
}
auto tcallable = dynamic_cast<TCallable*>(obj);
if(tcallable != nullptr)
{
if(key == "Tag")
{
gc->BarrierBegin();
tcallable->tag = value;
gc->BarrierEnd();
cse.back()->Push(gc,nullptr);
return false;
}
}
if(dynDict != nullptr)
{
if(dynDict->MethodExists(ls,"set" + key))
{
cse.back()->Push(gc,dynDict->CallMethod(ls,"set" + key, {value}));
}
else
{
dynDict->SetField(ls,key,value);
cse.back()->Push(gc,value);
}
return false;
}
if(dict != nullptr)
{
gc->BarrierBegin();
TObject fn = dict->GetValue("set" + key);
gc->BarrierEnd();
if(std::holds_alternative<THeapObjectHolder>(fn) && dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj) != nullptr)
{
return InvokeTwo(ls,fn, dict, value);
}
else
{
gc->BarrierBegin();
dict->SetValue(key, value);
stk->Push(gc, value);
gc->BarrierEnd();
return false;
}
}
stk->Push(gc, Undefined());
return false;
}
if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Streams::Stream>>(
instance)) {
auto strm =
std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(
instance);
auto netStrm = std::dynamic_pointer_cast<
Tesses::Framework::Streams::NetworkStream>(strm);
if (netStrm != nullptr) {
int64_t n0;
bool bc;
if (key == "Broadcast" && GetObject(value, bc))
netStrm->SetBroadcast(bc);
if (key == "NoDelay" && GetObject(value, bc))
netStrm->SetNoDelay(bc);
if (key == "ReuseAddress" && GetObject(value, bc))
netStrm->SetReuseAddress(bc);
if (key == "ReusePort" && GetObject(value, bc))
netStrm->SetReusePort(bc);
if (key == "MulticastTTL" && GetObject(value, n0))
netStrm->SetMulticastTTL((uint8_t)n0);
}
stk->Push(gc, Undefined());
return false;
}
return false;
}
if (std::holds_alternative<THeapObjectHolder>(instance)) {
auto obj = std::get<THeapObjectHolder>(instance).obj;
}
auto dict = dynamic_cast<TDictionary *>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject *>(obj);
if (cls != nullptr) {
gc->BarrierBegin();
auto obj =
cls->GetValue(cse.back()->callable->className, "set" + key);
gc->BarrierEnd();
TClosure *clos;
TCallable *callable;
if (GetObjectHeap(obj, clos)) {
this->AddCallStackEntry(ls, clos, {value});
return true;
} else if (GetObjectHeap(obj, callable)) {
cse.back()->Push(gc, callable->Call(ls, {value}));
return false;
}
gc->BarrierBegin();
cls->SetValue(cse.back()->callable->className, key, value);
gc->BarrierEnd();
cse.back()->Push(gc, value);
return false;
} else if (natObj != nullptr) {
cse.back()->Push(gc,
natObj->CallMethod(ls, "set" + key, {value}));
return false;
}
auto tcallable = dynamic_cast<TCallable *>(obj);
if (tcallable != nullptr) {
if (key == "Tag") {
gc->BarrierBegin();
tcallable->tag = value;
gc->BarrierEnd();
cse.back()->Push(gc, nullptr);
return false;
}
}
if (dynDict != nullptr) {
if (dynDict->MethodExists(ls, "set" + key)) {
cse.back()->Push(
gc, dynDict->CallMethod(ls, "set" + key, {value}));
} else {
dynDict->SetField(ls, key, value);
cse.back()->Push(gc, value);
}
return false;
}
if (dict != nullptr) {
gc->BarrierBegin();
TObject fn = dict->GetValue("set" + key);
gc->BarrierEnd();
if (std::holds_alternative<THeapObjectHolder>(fn) &&
dynamic_cast<TCallable *>(
std::get<THeapObjectHolder>(fn).obj) != nullptr) {
return InvokeTwo(ls, fn, dict, value);
} else {
gc->BarrierBegin();
dict->SetValue(key, value);
stk->Push(gc, value);
gc->BarrierEnd();
return false;
}
}
}
stk->Push(gc, Undefined());
}
return false;
}
} // namespace Tesses::CrossLang
+96 -104
View File
@@ -2,120 +2,112 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool InterperterThread::Sub(std::shared_ptr<GC> gc)
{
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
GCList ls(gc);
auto right = cse.back()->Pop(ls);
auto left = cse.back()->Pop(ls);
bool InterperterThread::Sub(std::shared_ptr<GC> gc) {
std::vector<CallStackEntry *> &cse = this->call_stack_entries;
GCList ls(gc);
auto right = cse.back()->Pop(ls);
auto left = cse.back()->Pop(ls);
if(std::holds_alternative<int64_t>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc,std::get<int64_t>(left) - std::get<int64_t>(right));
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<double>(right))
{
cse.back()->Push(gc,std::get<double>(left) - std::get<double>(right));
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc,std::get<double>(left) - std::get<int64_t>(right));
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right))
{
cse.back()->Push(gc,std::get<int64_t>(left) - std::get<double>(right));
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right))
{
cse.back()->Push(gc, (int64_t)(std::get<char>(left) - std::get<char>(right)));
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc, (int64_t)(std::get<char>(left) - std::get<int64_t>(right)));
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right))
{
cse.back()->Push(gc, (int64_t)(std::get<int64_t>(left) - std::get<char>(right)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) - (*r)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) - (*r)));
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(gc,
std::get<int64_t>(left) - std::get<int64_t>(right));
}
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
if(cls != nullptr)
{
gc->BarrierBegin();
auto obj=cls->GetValue(cse.back()->callable->className,"operator-");
gc->BarrierEnd();
TClosure* clos;
TCallable* callable;
if(GetObjectHeap(obj,clos))
{
this->AddCallStackEntry(ls,clos,{right});
return true;
}
else if(GetObjectHeap(obj,callable))
{
cse.back()->Push(gc,callable->Call(ls,{right}));
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
else if(natObj != nullptr)
{
cse.back()->Push(gc, natObj->CallMethod(ls,"operator-",{right}));
else if (std::holds_alternative<double>(left) &&
std::holds_alternative<double>(right)) {
cse.back()->Push(gc, std::get<double>(left) - std::get<double>(right));
} else if (std::holds_alternative<double>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(gc, std::get<double>(left) - std::get<int64_t>(right));
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<double>(right)) {
cse.back()->Push(gc, std::get<int64_t>(left) - std::get<double>(right));
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<char>(right)) {
cse.back()->Push(
gc, (int64_t)(std::get<char>(left) - std::get<char>(right)));
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(
gc, (int64_t)(std::get<char>(left) - std::get<int64_t>(right)));
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<char>(right)) {
cse.back()->Push(
gc, (int64_t)(std::get<int64_t>(left) - std::get<char>(right)));
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) &&
std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)) {
auto &l =
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto &r =
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(
gc,
std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) - (*r)));
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) &&
std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) {
auto &l =
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto &r =
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(
gc,
std::make_shared<Tesses::Framework::Date::DateTime>((*l) - (*r)));
} else if (std::holds_alternative<THeapObjectHolder>(left)) {
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary *>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject *>(obj);
if (cls != nullptr) {
gc->BarrierBegin();
auto obj =
cls->GetValue(cse.back()->callable->className, "operator-");
gc->BarrierEnd();
TClosure *clos;
TCallable *callable;
if (GetObjectHeap(obj, clos)) {
this->AddCallStackEntry(ls, clos, {right});
return true;
} else if (GetObjectHeap(obj, callable)) {
cse.back()->Push(gc, callable->Call(ls, {right}));
return false;
}
else if(dict != nullptr)
{
gc->BarrierBegin();
TObject fn = dict->GetValue("operator-");
gc->BarrierEnd();
return InvokeTwo(ls,fn,left,right);
}
else if(dynDict != nullptr)
{
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator-",{right}));
return false;
}
else
{
cse.back()->Push(gc,Undefined());
}
}
else
{
cse.back()->Push(gc, Undefined());
return false;
} else if (natObj != nullptr) {
cse.back()->Push(gc, natObj->CallMethod(ls, "operator-", {right}));
return false;
} else if (dict != nullptr) {
gc->BarrierBegin();
TObject fn = dict->GetValue("operator-");
gc->BarrierEnd();
return InvokeTwo(ls, fn, left, right);
} else if (dynDict != nullptr) {
cse.back()->Push(gc, dynDict->CallMethod(ls, "operator-", {right}));
return false;
} else {
cse.back()->Push(gc, Undefined());
}
return false;
} else {
cse.back()->Push(gc, Undefined());
}
}
return false;
}
} // namespace Tesses::CrossLang
+73 -94
View File
@@ -2,105 +2,84 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool ToBool(TObject obj)
{
if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(obj))
{
return true;
}
if(std::holds_alternative<TVMVersion>(obj))
{
auto v = std::get<TVMVersion>(obj);
return v.AsLong() != 0;
}
if(std::holds_alternative<std::string>(obj))
{
return !std::get<std::string>(obj).empty();
}
else if(std::holds_alternative<int64_t>(obj))
{
return std::get<int64_t>(obj) != 0;
}
else if(std::holds_alternative<double>(obj))
{
return std::get<double>(obj);
}
else if(std::holds_alternative<bool>(obj))
{
return std::get<bool>(obj);
}
else if(std::holds_alternative<char>(obj))
{
return std::get<char>(obj) != 0;
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(obj))
{
auto& dt = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(obj);
return !(dt->Year() == 1970 && dt->Month() == 1 && dt->Day() == 1 && dt->Hour() == 0 && dt->Minute() == 0 && dt->Second() == 0 && !dt->IsLocal());
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(obj))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(obj)->TotalSeconds() != 0;
}
else if(std::holds_alternative<Tesses::Framework::Uuid>(obj))
{
auto& uuid = std::get<Tesses::Framework::Uuid>(obj);
return !uuid.IsEmpty();
}
else if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto o = std::get<THeapObjectHolder>(obj).obj;
auto ls = dynamic_cast<TList*>(o);
auto aarray = dynamic_cast<TAssociativeArray*>(o);
auto dict = dynamic_cast<TDictionary*>(o);
auto ba = dynamic_cast<TByteArray*>(o);
auto nat = dynamic_cast<TNative*>(o);
auto thrd = dynamic_cast<ThreadHandle*>(o);
auto natObj = dynamic_cast<TNativeObject*>(o);
auto any = dynamic_cast<TAny*>(o);
auto cls = dynamic_cast<TClassObject*>(o);
if(cls!=nullptr) return true;
if(natObj != nullptr) return natObj->ToBool();
if(any != nullptr) return any->any.has_value();
if(ls != nullptr)
{
return ls->Count() != 0;
}
if(aarray != nullptr)
{
return aarray->Count() != 0;
}
else if(dict != nullptr)
{
return !dict->items.empty();
}
else if(ba != nullptr)
{
return !ba->data.empty();
}
else if(nat != nullptr)
{
return !nat->GetDestroyed();
}
else if(thrd != nullptr)
{
return !thrd->hasReturned;
}
return true;
}
return false;
bool ToBool(TObject obj) {
if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(obj)) {
return true;
}
}
if (std::holds_alternative<TVMVersion>(obj)) {
auto v = std::get<TVMVersion>(obj);
return v.AsLong() != 0;
}
if (std::holds_alternative<std::string>(obj)) {
return !std::get<std::string>(obj).empty();
} else if (std::holds_alternative<int64_t>(obj)) {
return std::get<int64_t>(obj) != 0;
} else if (std::holds_alternative<double>(obj)) {
return std::get<double>(obj);
} else if (std::holds_alternative<bool>(obj)) {
return std::get<bool>(obj);
} else if (std::holds_alternative<char>(obj)) {
return std::get<char>(obj) != 0;
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(obj)) {
auto &dt =
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(obj);
return !(dt->Year() == 1970 && dt->Month() == 1 && dt->Day() == 1 &&
dt->Hour() == 0 && dt->Minute() == 0 && dt->Second() == 0 &&
!dt->IsLocal());
} else if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(obj)) {
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(obj)
->TotalSeconds() != 0;
} else if (std::holds_alternative<Tesses::Framework::Uuid>(obj)) {
auto &uuid = std::get<Tesses::Framework::Uuid>(obj);
return !uuid.IsEmpty();
} else if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto o = std::get<THeapObjectHolder>(obj).obj;
auto ls = dynamic_cast<TList *>(o);
auto aarray = dynamic_cast<TAssociativeArray *>(o);
auto dict = dynamic_cast<TDictionary *>(o);
auto ba = dynamic_cast<TByteArray *>(o);
auto nat = dynamic_cast<TNative *>(o);
auto thrd = dynamic_cast<ThreadHandle *>(o);
auto natObj = dynamic_cast<TNativeObject *>(o);
auto any = dynamic_cast<TAny *>(o);
auto cls = dynamic_cast<TClassObject *>(o);
if (cls != nullptr)
return true;
if (natObj != nullptr)
return natObj->ToBool();
if (any != nullptr)
return any->any.has_value();
if (ls != nullptr) {
return ls->Count() != 0;
}
if (aarray != nullptr) {
return aarray->Count() != 0;
} else if (dict != nullptr) {
return !dict->items.empty();
} else if (ba != nullptr) {
return !ba->data.empty();
} else if (nat != nullptr) {
return !nat->GetDestroyed();
} else if (thrd != nullptr) {
return !thrd->hasReturned;
}
return true;
}
return false;
}
} // namespace Tesses::CrossLang
+104 -122
View File
@@ -2,132 +2,114 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
std::string ToString(std::shared_ptr<GC> gc, TObject o)
{
if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(o))
{
return std::get<Tesses::Framework::Filesystem::VFSPath>(o).ToString();
}
if(std::holds_alternative<std::string>(o))
{
return std::get<std::string>(o);
}
if(std::holds_alternative<TVMVersion>(o))
{
return std::get<TVMVersion>(o).ToString();
}
if(std::holds_alternative<int64_t>(o))
{
return std::to_string(std::get<int64_t>(o));
}
if(std::holds_alternative<double>(o))
{
return std::to_string(std::get<double>(o));
}
if(std::holds_alternative<char>(o))
{
return std::string{std::get<char>(o)};
}
if(std::holds_alternative<std::nullptr_t>(o))
{
return "null";
}
if(std::holds_alternative<Undefined>(o))
{
return "undefined";
}
if(std::holds_alternative<bool>(o))
{
return std::get<bool>(o) ? "true" : "false";
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(o))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(o)->ToString();
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(o))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(o)->ToString(false);
}
if(std::holds_alternative<Tesses::Framework::Uuid>(o))
{
return std::get<Tesses::Framework::Uuid>(o).ToString(Framework::UuidStringifyConfig::LowercaseNoCurly);
}
if(std::holds_alternative<THeapObjectHolder>(o))
{
auto obj = std::get<THeapObjectHolder>(o).obj;
auto dict = dynamic_cast<TDictionary*>(obj);
auto list = dynamic_cast<TList*>(obj);
auto bArray = dynamic_cast<TByteArray*>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
auto aArray = dynamic_cast<TAssociativeArray*>(obj);
if(aArray != nullptr)
{
std::string str={};
gc->BarrierBegin();
bool first=true;
for(auto item : aArray->items)
{
if(!first) str.push_back('\n');
first=false;
str.push_back('[');
str.append(Json_Encode(item.first));
str.append("] = ");
str.append(Json_Encode(item.second));
str.append(";");
}
gc->BarrierEnd();
return str;
}
if(cls != nullptr)
{
auto res = cls->GetValue("","ToString");
TCallable* call;
GCList ls(gc);
if(GetObjectHeap(res,call)) return ToString(gc, call->Call(ls,{}));
return cls->TypeName();
}
if(natObj != nullptr)
{
GCList ls(gc);
TObject o=natObj->CallMethod(ls,"ToString",{});
return ToString(gc, o);
}
if(dict != nullptr)
{
GCList ls(gc);
if(dict->MethodExists(ls,"ToString"))
return ToString(gc,dict->CallMethod(ls,"ToString",{}));
else
{
return Json_Encode(dict);
}
}
else if(bArray != nullptr)
{
return std::string(bArray->data.begin(),bArray->data.end());
}
else if(list != nullptr)
{
return Json_Encode(list);
}
}
return "";
std::string ToString(std::shared_ptr<GC> gc, TObject o) {
if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(o)) {
return std::get<Tesses::Framework::Filesystem::VFSPath>(o).ToString();
}
}
if (std::holds_alternative<std::string>(o)) {
return std::get<std::string>(o);
}
if (std::holds_alternative<TVMVersion>(o)) {
return std::get<TVMVersion>(o).ToString();
}
if (std::holds_alternative<int64_t>(o)) {
return std::to_string(std::get<int64_t>(o));
}
if (std::holds_alternative<double>(o)) {
return std::to_string(std::get<double>(o));
}
if (std::holds_alternative<char>(o)) {
return std::string{std::get<char>(o)};
}
if (std::holds_alternative<std::nullptr_t>(o)) {
return "null";
}
if (std::holds_alternative<Undefined>(o)) {
return "undefined";
}
if (std::holds_alternative<bool>(o)) {
return std::get<bool>(o) ? "true" : "false";
}
if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::DateTime>>(o)) {
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(o)
->ToString();
}
if (std::holds_alternative<
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(o)) {
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(o)
->ToString(false);
}
if (std::holds_alternative<Tesses::Framework::Uuid>(o)) {
return std::get<Tesses::Framework::Uuid>(o).ToString(
Framework::UuidStringifyConfig::LowercaseNoCurly);
}
if (std::holds_alternative<THeapObjectHolder>(o)) {
auto obj = std::get<THeapObjectHolder>(o).obj;
auto dict = dynamic_cast<TDictionary *>(obj);
auto list = dynamic_cast<TList *>(obj);
auto bArray = dynamic_cast<TByteArray *>(obj);
auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject *>(obj);
auto aArray = dynamic_cast<TAssociativeArray *>(obj);
if (aArray != nullptr) {
std::string str = {};
gc->BarrierBegin();
bool first = true;
for (auto item : aArray->items) {
if (!first)
str.push_back('\n');
first = false;
str.push_back('[');
str.append(Json_Encode(item.first));
str.append("] = ");
str.append(Json_Encode(item.second));
str.append(";");
}
gc->BarrierEnd();
return str;
}
if (cls != nullptr) {
auto res = cls->GetValue("", "ToString");
TCallable *call;
GCList ls(gc);
if (GetObjectHeap(res, call))
return ToString(gc, call->Call(ls, {}));
return cls->TypeName();
}
if (natObj != nullptr) {
GCList ls(gc);
TObject o = natObj->CallMethod(ls, "ToString", {});
return ToString(gc, o);
}
if (dict != nullptr) {
GCList ls(gc);
if (dict->MethodExists(ls, "ToString"))
return ToString(gc, dict->CallMethod(ls, "ToString", {}));
else {
return Json_Encode(dict);
}
} else if (bArray != nullptr) {
return std::string(bArray->data.begin(), bArray->data.end());
} else if (list != nullptr) {
return Json_Encode(list);
}
}
return "";
}
} // namespace Tesses::CrossLang
+85 -99
View File
@@ -1,107 +1,93 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TObject TCallable::CallWithFatalError(GCList& ls, std::vector<TObject> args)
{
try {
return Call(ls,args);
}
catch(VMByteCodeException& ex)
{
ThrowFatalError(ex);
}
catch(VMException& ex)
{
ThrowFatalError(ex);
}
catch(SyntaxException& ex)
{
ThrowFatalError(ex);
}
catch(std::runtime_error& ex)
{
ThrowFatalError(ex);
}
catch(std::exception& ex)
{
ThrowFatalError(ex);
}
return (int64_t)1;
TObject TCallable::CallWithFatalError(GCList &ls, std::vector<TObject> args) {
try {
return Call(ls, args);
} catch (VMByteCodeException &ex) {
ThrowFatalError(ex);
} catch (VMException &ex) {
ThrowFatalError(ex);
} catch (SyntaxException &ex) {
ThrowFatalError(ex);
} catch (std::runtime_error &ex) {
ThrowFatalError(ex);
} catch (std::exception &ex) {
ThrowFatalError(ex);
}
void ThrowFatalError(std::exception& ex)
{
using namespace Tesses::Framework::TextStreams;
std::exception* ex2 = &ex;
auto clexcept = dynamic_cast<VMByteCodeException*>(ex2);
auto clrtexcept = dynamic_cast<VMException*>(ex2);
auto compiler = dynamic_cast<SyntaxException*>(ex2);
Tesses::Framework::TextStreams::ConsoleWriter error(true);
if(clexcept != nullptr)
{
error.WriteLine("CrossLang has encountered a fatal exception");
error.WriteLine();
error.WriteLine(ToString(clexcept->GetGCList()->GetGC(),clexcept->exception));
error.WriteLine();
error.WriteLine("STACKTRACE:");
for(auto ittr = clexcept->stack_trace.crbegin(); ittr != clexcept->stack_trace.crend(); ittr++)
{
auto item = *ittr;
std::string text = "\t";
text += item->callable->closure->name.value_or((std::string)"<Closure>");
text += "(";
bool first=true;
for(auto& arg : item->callable->closure->args)
{
if(!first) text += ", ";
text += arg;
first=false;
}
text += ")";
if(item->srcline >= 1)
{
text += " at ";
text += item->srcfile;
text += ":";
text += std::to_string(item->srcline);
}
error.WriteLine(text);
}
return (int64_t)1;
}
void ThrowFatalError(std::exception &ex) {
using namespace Tesses::Framework::TextStreams;
std::exception *ex2 = &ex;
auto clexcept = dynamic_cast<VMByteCodeException *>(ex2);
auto clrtexcept = dynamic_cast<VMException *>(ex2);
auto compiler = dynamic_cast<SyntaxException *>(ex2);
Tesses::Framework::TextStreams::ConsoleWriter error(true);
exit(1);
}
if(clrtexcept != nullptr)
{
error.WriteLine("CrossLang has encountered a fatal runtime exception");
error.WriteLine();
error.WriteLine(clrtexcept->what());
exit(1);
}
if(compiler != nullptr)
{
error.WriteLine("CrossLang has encountered a compiler error");
error.WriteLine();
error.WriteLine(compiler->Message());
error.WriteLine();
auto li = compiler->LineInfo();
error.Write("in file: ");
error.Write(li.filename);
error.Write(":");
error.Write((int64_t)li.line);
error.Write(":");
error.Write((int64_t)li.column);
error.Write(":");
error.WriteLine((int64_t)li.offset);
exit(1);
}
error.WriteLine("CrossLang has encountered a fatal C++ exception");
if (clexcept != nullptr) {
error.WriteLine("CrossLang has encountered a fatal exception");
error.WriteLine();
error.Write("what(): ");
error.WriteLine(ex2->what());
error.WriteLine(
ToString(clexcept->GetGCList()->GetGC(), clexcept->exception));
error.WriteLine();
error.WriteLine("STACKTRACE:");
for (auto ittr = clexcept->stack_trace.crbegin();
ittr != clexcept->stack_trace.crend(); ittr++) {
auto item = *ittr;
std::string text = "\t";
text += item->callable->closure->name.value_or(
(std::string) "<Closure>");
text += "(";
bool first = true;
for (auto &arg : item->callable->closure->args) {
if (!first)
text += ", ";
text += arg;
first = false;
}
text += ")";
if (item->srcline >= 1) {
text += " at ";
text += item->srcfile;
text += ":";
text += std::to_string(item->srcline);
}
error.WriteLine(text);
}
exit(1);
}
}
if (clrtexcept != nullptr) {
error.WriteLine("CrossLang has encountered a fatal runtime exception");
error.WriteLine();
error.WriteLine(clrtexcept->what());
exit(1);
}
if (compiler != nullptr) {
error.WriteLine("CrossLang has encountered a compiler error");
error.WriteLine();
error.WriteLine(compiler->Message());
error.WriteLine();
auto li = compiler->LineInfo();
error.Write("in file: ");
error.Write(li.filename);
error.Write(":");
error.Write((int64_t)li.line);
error.Write(":");
error.Write((int64_t)li.column);
error.Write(":");
error.WriteLine((int64_t)li.offset);
exit(1);
}
error.WriteLine("CrossLang has encountered a fatal C++ exception");
error.WriteLine();
error.Write("what(): ");
error.WriteLine(ex2->what());
exit(1);
}
} // namespace Tesses::CrossLang
+406 -446
View File
@@ -1,453 +1,413 @@
#include "CrossLang.hpp"
#include <cstring>
#include <filesystem>
#include <iostream>
namespace Tesses::CrossLang
{
namespace Tesses::CrossLang {
TFile* TFile::Create(GCList& ls)
{
TFile* f = new TFile();
f->icon = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(f);
_gc->Watch(f);
return f;
}
TFile* TFile::Create(GCList* ls)
{
TFile* f = new TFile();
f->icon=-1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(f);
_gc->Watch(f);
return f;
}
void TFileChunk::Mark()
{
if(this->marked) return;
this->marked=true;
this->file->Mark();
}
TFileChunk* TFileChunk::Create(GCList& ls)
{
TFileChunk* chk = new TFileChunk();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(chk);
_gc->Watch(chk);
return chk;
}
TFileChunk* TFileChunk::Create(GCList* ls)
{
TFileChunk* chk = new TFileChunk();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(chk);
_gc->Watch(chk);
return chk;
}
void TFile::Mark()
{
if(this->marked) return;
this->marked=true;
for(auto item : this->chunks)
item->Mark();
}
void TFile::Skip(std::shared_ptr<Tesses::Framework::Streams::Stream> stream,size_t len)
{
if(stream->CanSeek())
{
stream->Seek((int64_t)len,Tesses::Framework::Streams::SeekOrigin::Current);
}
else{
uint8_t* buffer=new uint8_t[len];
Ensure(stream,buffer,len);
delete[] buffer;
}
}
void TFile::Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> stream, uint8_t* buffer,size_t len)
{
size_t read = stream->ReadBlock(buffer, len);
if(read < len) throw VMException("End of file, could not read " + std::to_string((int64_t)len) + " byte(s)., offset=" + std::to_string(stream->GetLength()));
}
std::string TFile::EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> stream)
{
auto len = EnsureInt(stream);
if(len == 0) return {};
std::string str={};
str.resize((size_t)len);
Ensure(stream,(uint8_t*)str.data(),str.size());
return str;
}
uint32_t TFile::EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> stream)
{
uint8_t buffer[4];
Ensure(stream,buffer,4);
return BitConverter::ToUint32BE(buffer[0]);
}
std::string TFile::GetString(std::shared_ptr<Tesses::Framework::Streams::Stream> stream)
{
uint32_t index=EnsureInt(stream);
if(index >= this->strings.size()) throw VMException("String does not exist in TCrossVM file, expected string index: " + std::to_string(index) + ", total strings: " + std::to_string(this->strings.size()));
return this->strings[index];
}
void TFile::EnsureCanRunInCrossLang()
{
if(this->vms.empty()) return;
for(auto item : this->vms)
{
if(item.first == VMName)
{
return;
}
}
std::string errorMessage="The virtual machines supported are:\n";
for(auto item : this->vms)
{
errorMessage += item.first + "\n\t" + item.second + "\n";
}
throw VMException(errorMessage);
}
TDictionary* TFile::MetadataDecode(GCList& ls, size_t midx)
{
if(midx >= this->metadata.size()) return nullptr;
if(this->metadata[midx].second.empty()) return nullptr;
if(this->metadata[midx].second[0] != 8) return nullptr;
size_t index = 0;
auto& bytes = this->metadata[midx].second;
std::function<TObject()> parseEnt;
parseEnt = [&]()->TObject {
if(index >= bytes.size()) throw std::out_of_range("Abrupt end of metadata");
switch(bytes[index++])
{
case 0:
return false;
case 1:
return true;
case 2:
return nullptr;
case 3:
{
if(index + 8 <= bytes.size())
{
auto val= BitConverter::ToUint64BE(bytes[index]);
index+=8;
int64_t val2;
memcpy(&val2,&val,sizeof(val));
return val2;
}
else throw std::out_of_range("Abrupt end of metadata");
}
break;
case 4:
{
if(index + 8 <= bytes.size())
{
auto val= BitConverter::ToDoubleBE(bytes[index]);
index+=8;
return val;
}
else throw std::out_of_range("Abrupt end of metadata");
}
break;
case 5:
if(index + 1 <= bytes.size())
{
return (char)bytes[index++];
}
else throw std::out_of_range("Abrupt end of metadata");
break;
case 6:
{
if(index + 4 <= bytes.size())
{
auto val= BitConverter::ToUint32BE(bytes[index]);
index+=4;
return this->strings.at((size_t)val);
} else throw std::out_of_range("Abrupt end of metadata");
}
break;
case 7:
{
if(index + 4 <= bytes.size())
{
auto val= BitConverter::ToUint32BE(bytes[index]);
index+=4;
std::vector<TObject> items;
for(uint32_t i = 0; i < val; i++)
{
items.push_back(parseEnt());
}
return TList::Create(ls,items.begin(),items.end());
} else throw std::out_of_range("Abrupt end of metadata");
}
break;
case 8:
if(index + 4 <= bytes.size())
{
auto val= BitConverter::ToUint32BE(bytes[index]);
index+=4;
std::vector<TDItem> items;
for(uint32_t i = 0; i < val; i++)
{
if(index + 4 <= bytes.size())
{
auto val2= BitConverter::ToUint32BE(bytes[index]);
index+=4;
std::string& text=this->strings.at((size_t)val2);
items.emplace_back(text,parseEnt());
} else throw std::out_of_range("Abrupt end of metadata");
}
return TDictionary::Create(ls, items.begin(),items.end());
}else throw std::out_of_range("Abrupt end of metadata");
break;
case 9:
{
if(index + 4 <= bytes.size())
{
auto val= BitConverter::ToUint32BE(bytes[index]);
index+=4;
auto ba = TByteArray::Create(ls);
ba->data = this->resources.at((size_t)val);
return ba;
} else throw std::out_of_range("Abrupt end of metadata");
}
break;
case 10:
{
if(index + 4 <= bytes.size())
{
auto val= BitConverter::ToUint32BE(bytes[index]);
index+=4;
return std::make_shared<EmbedStream>(ls.GetGC(),this,val);
} else throw std::out_of_range("Abrupt end of metadata");
}
break;
case 11:
{
auto data = parseEnt();
TDictionary* dict;
if(GetObjectHeap(data,dict))
{
return std::make_shared<EmbedDirectory>(ls.GetGC(),dict);
}
else return Undefined();
}
break;
case 12:
{
if(index + 4 <= bytes.size())
{
auto val= BitConverter::ToUint32BE(bytes[index]);
index+=4;
ls.GetGC()->BarrierBegin();
auto em = TExternalMethod::Create(ls,"",{},[val,this](GCList& ls, std::vector<TObject> args)->TObject {
return std::make_shared<EmbedStream>(ls.GetGC(),this,val);
});
em->watch.push_back(this);
ls.GetGC()->BarrierEnd();
return em;
} else throw std::out_of_range("Abrupt end of metadata");
}
break;
default:
throw std::runtime_error("Invalid metadata opcode");
}
};
TDictionary* dict_res;
TObject ent = parseEnt();
if(GetObjectHeap(ent, dict_res)) return dict_res;
return nullptr;
}
void TFile::Load(std::shared_ptr<GC> gc, std::shared_ptr<Tesses::Framework::Streams::Stream> stream)
{
uint8_t main_header[18];
Ensure(stream,main_header,sizeof(main_header));
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header+8);
if(version.CompareToRuntime() == 1)
{
throw VMException("Runtime is too old.");
}
TVMVersion v2(main_header+13);
this->version = v2;
size_t _len = (size_t)EnsureInt(stream);
char table_name[4];
for(size_t i = 0;i < _len; i++)
{
Ensure(stream,(uint8_t*)table_name,sizeof(table_name));
size_t tableLen = (size_t)EnsureInt(stream);
if(strncmp(table_name,"NAME",4) == 0)
{
this->name = GetString(stream);
}
else if(strncmp(table_name,"INFO",4) == 0)
{
this->info = GetString(stream);
}
else if(strncmp(table_name,"DEPS",4) == 0) //dependencies
{
std::string name = GetString(stream);
uint8_t version_bytes[5];
Ensure(stream,version_bytes,sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
this->dependencies.push_back(std::pair<std::string,TVMVersion>(name, depVersion));
}
else if(strncmp(table_name,"TOOL",4) == 0) //compile tools (for package manager)
{
std::string name = GetString(stream);
uint8_t version_bytes[5];
Ensure(stream,version_bytes,sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
this->tools.push_back(std::pair<std::string,TVMVersion>(name, depVersion));
}
else if(strncmp(table_name,"RESO",4) == 0) //resources (using embed)
{
auto& data = this->resources.emplace_back(tableLen);
Ensure(stream,data.data(), data.size());
}
else if(strncmp(table_name,"CHKS",4) == 0 && gc != nullptr) //chunks
{
GCList ls(gc);
size_t chunkCount = (size_t)EnsureInt(stream);
for(size_t j = 0; j < chunkCount; j++)
{
auto chunk = TFileChunk::Create(ls);
chunk->file = this;
size_t argCount = (size_t)EnsureInt(stream);
for(size_t k = 0; k < argCount; k++)
{
chunk->args.push_back(GetString(stream));
}
size_t len = (size_t)EnsureInt(stream);
chunk->code.resize(len);
Ensure(stream,chunk->code.data(),len);
//reader.ReadIntoBuffer(chunk->code);
this->chunks.push_back(chunk);
}
}
else if(strncmp(table_name,"FUNS",4) == 0) //functions
{
size_t funLength = (size_t)EnsureInt(stream);
for(size_t j = 0; j < funLength;j++)
{
std::vector<std::string> fnParts;
uint32_t fnPartsC = EnsureInt(stream);
for(uint32_t k = 0; k < fnPartsC; k++)
{
fnParts.push_back(GetString(stream));
}
uint32_t fnNumber = EnsureInt(stream);
this->functions.push_back(std::pair<std::vector<std::string>,uint32_t>(fnParts,fnNumber));
}
}
else if(strncmp(table_name,"STRS",4) == 0) //strings
{
size_t strsLen = (size_t)EnsureInt(stream);
for(size_t j = 0;j < strsLen;j++)
{
this->strings.push_back(EnsureString(stream));
}
}
else if(strncmp(table_name,"ICON",4) == 0) //icon
{
this->icon = (int32_t)EnsureInt(stream);
}
else if(strncmp(table_name,"MACH",4) == 0) //machine
{
std::string name = GetString(stream);
std::string howToGet = GetString(stream);
this->vms.push_back(std::pair<std::string,std::string>(name,howToGet));
}
else if(strncmp(table_name,"CLSS",4) == 0) //classes
{
uint32_t clsCnt = EnsureInt(stream);
for(uint32_t j = 0; j < clsCnt; j++)
{
TClass cls;
cls.documentation= GetString(stream);
uint32_t name_cnt = EnsureInt(stream);
for(uint32_t k = 0; k < name_cnt; k++)
{
cls.name.push_back(GetString(stream));
}
name_cnt = EnsureInt(stream);
for(uint32_t k = 0; k < name_cnt; k++)
{
cls.inherits.push_back(GetString(stream));
}
name_cnt = EnsureInt(stream);
for(uint32_t k = 0; k < name_cnt; k++)
{
TClassEntry ent;
Ensure(stream,main_header,1);
uint8_t sig = main_header[0];
ent.isAbstract = (sig & 0b00001000) != 0;
ent.isFunction = (sig & 0b00000100) == 0;
ent.modifier = (TClassModifier)(sig & 3);
ent.documentation = GetString(stream);
ent.name = GetString(stream);
uint32_t arglen = EnsureInt(stream);
for(uint32_t l = 0; l < arglen; l++)
ent.args.push_back(GetString(stream));
ent.chunkId = EnsureInt(stream);
cls.entry.push_back(ent);
}
this->classes.push_back(cls);
}
}
else if(strncmp(table_name,"META",4) == 0) //structured metadata
{
if(tableLen > 4)
{
auto name = this->GetString(stream);
auto& data = this->metadata.emplace_back(name, std::vector<uint8_t>(tableLen-4));
Ensure(stream,data.second.data(), tableLen-4);
}
else throw VMException("meta tag is not valid");
}
else
{
auto& data = this->sections.emplace_back(std::string(table_name, 4), std::vector<uint8_t>(tableLen));
Ensure(stream,data.second.data(), tableLen);
}
}
}
TFile *TFile::Create(GCList &ls) {
TFile *f = new TFile();
f->icon = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(f);
_gc->Watch(f);
return f;
}
TFile *TFile::Create(GCList *ls) {
TFile *f = new TFile();
f->icon = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(f);
_gc->Watch(f);
return f;
}
void TFileChunk::Mark() {
if (this->marked)
return;
this->marked = true;
this->file->Mark();
}
TFileChunk *TFileChunk::Create(GCList &ls) {
TFileChunk *chk = new TFileChunk();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(chk);
_gc->Watch(chk);
return chk;
}
TFileChunk *TFileChunk::Create(GCList *ls) {
TFileChunk *chk = new TFileChunk();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(chk);
_gc->Watch(chk);
return chk;
}
void TFile::Mark() {
if (this->marked)
return;
this->marked = true;
for (auto item : this->chunks)
item->Mark();
}
void TFile::Skip(std::shared_ptr<Tesses::Framework::Streams::Stream> stream,
size_t len) {
if (stream->CanSeek()) {
stream->Seek((int64_t)len,
Tesses::Framework::Streams::SeekOrigin::Current);
} else {
uint8_t *buffer = new uint8_t[len];
Ensure(stream, buffer, len);
delete[] buffer;
}
}
void TFile::Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> stream,
uint8_t *buffer, size_t len) {
size_t read = stream->ReadBlock(buffer, len);
if (read < len)
throw VMException(
"End of file, could not read " + std::to_string((int64_t)len) +
" byte(s)., offset=" + std::to_string(stream->GetLength()));
}
std::string TFile::EnsureString(
std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
auto len = EnsureInt(stream);
if (len == 0)
return {};
std::string str = {};
str.resize((size_t)len);
Ensure(stream, (uint8_t *)str.data(), str.size());
return str;
}
uint32_t
TFile::EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
uint8_t buffer[4];
Ensure(stream, buffer, 4);
return BitConverter::ToUint32BE(buffer[0]);
}
std::string
TFile::GetString(std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
uint32_t index = EnsureInt(stream);
if (index >= this->strings.size())
throw VMException(
"String does not exist in TCrossVM file, expected string index: " +
std::to_string(index) +
", total strings: " + std::to_string(this->strings.size()));
return this->strings[index];
}
void TFile::EnsureCanRunInCrossLang() {
if (this->vms.empty())
return;
for (auto item : this->vms) {
if (item.first == VMName) {
return;
}
}
std::string errorMessage = "The virtual machines supported are:\n";
for (auto item : this->vms) {
errorMessage += item.first + "\n\t" + item.second + "\n";
}
throw VMException(errorMessage);
}
TDictionary *TFile::MetadataDecode(GCList &ls, size_t midx) {
if (midx >= this->metadata.size())
return nullptr;
if (this->metadata[midx].second.empty())
return nullptr;
if (this->metadata[midx].second[0] != 8)
return nullptr;
size_t index = 0;
auto &bytes = this->metadata[midx].second;
std::function<TObject()> parseEnt;
parseEnt = [&]() -> TObject {
if (index >= bytes.size())
throw std::out_of_range("Abrupt end of metadata");
switch (bytes[index++]) {
case 0:
return false;
case 1:
return true;
case 2:
return nullptr;
case 3: {
if (index + 8 <= bytes.size()) {
auto val = BitConverter::ToUint64BE(bytes[index]);
index += 8;
int64_t val2;
memcpy(&val2, &val, sizeof(val));
return val2;
} else
throw std::out_of_range("Abrupt end of metadata");
} break;
case 4: {
if (index + 8 <= bytes.size()) {
auto val = BitConverter::ToDoubleBE(bytes[index]);
index += 8;
return val;
} else
throw std::out_of_range("Abrupt end of metadata");
} break;
case 5:
if (index + 1 <= bytes.size()) {
return (char)bytes[index++];
} else
throw std::out_of_range("Abrupt end of metadata");
break;
case 6: {
if (index + 4 <= bytes.size()) {
auto val = BitConverter::ToUint32BE(bytes[index]);
index += 4;
return this->strings.at((size_t)val);
} else
throw std::out_of_range("Abrupt end of metadata");
} break;
case 7: {
if (index + 4 <= bytes.size()) {
auto val = BitConverter::ToUint32BE(bytes[index]);
index += 4;
std::vector<TObject> items;
for (uint32_t i = 0; i < val; i++) {
items.push_back(parseEnt());
}
return TList::Create(ls, items.begin(), items.end());
} else
throw std::out_of_range("Abrupt end of metadata");
} break;
case 8:
if (index + 4 <= bytes.size()) {
auto val = BitConverter::ToUint32BE(bytes[index]);
index += 4;
std::vector<TDItem> items;
for (uint32_t i = 0; i < val; i++) {
if (index + 4 <= bytes.size()) {
auto val2 = BitConverter::ToUint32BE(bytes[index]);
index += 4;
std::string &text = this->strings.at((size_t)val2);
items.emplace_back(text, parseEnt());
} else
throw std::out_of_range("Abrupt end of metadata");
}
return TDictionary::Create(ls, items.begin(), items.end());
} else
throw std::out_of_range("Abrupt end of metadata");
break;
case 9: {
if (index + 4 <= bytes.size()) {
auto val = BitConverter::ToUint32BE(bytes[index]);
index += 4;
auto ba = TByteArray::Create(ls);
ba->data = this->resources.at((size_t)val);
return ba;
} else
throw std::out_of_range("Abrupt end of metadata");
} break;
case 10: {
if (index + 4 <= bytes.size()) {
auto val = BitConverter::ToUint32BE(bytes[index]);
index += 4;
return std::make_shared<EmbedStream>(ls.GetGC(), this, val);
} else
throw std::out_of_range("Abrupt end of metadata");
} break;
case 11: {
auto data = parseEnt();
TDictionary *dict;
if (GetObjectHeap(data, dict)) {
return std::make_shared<EmbedDirectory>(ls.GetGC(), dict);
} else
return Undefined();
} break;
case 12: {
if (index + 4 <= bytes.size()) {
auto val = BitConverter::ToUint32BE(bytes[index]);
index += 4;
ls.GetGC()->BarrierBegin();
auto em = TExternalMethod::Create(
ls, "", {},
[val, this](GCList &ls,
std::vector<TObject> args) -> TObject {
return std::make_shared<EmbedStream>(ls.GetGC(), this,
val);
});
em->watch.push_back(this);
ls.GetGC()->BarrierEnd();
return em;
} else
throw std::out_of_range("Abrupt end of metadata");
} break;
default:
throw std::runtime_error("Invalid metadata opcode");
}
};
TDictionary *dict_res;
TObject ent = parseEnt();
if (GetObjectHeap(ent, dict_res))
return dict_res;
return nullptr;
}
void TFile::Load(std::shared_ptr<GC> gc,
std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
uint8_t main_header[18];
Ensure(stream, main_header, sizeof(main_header));
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header + 8);
if (version.CompareToRuntime() == 1) {
throw VMException("Runtime is too old.");
}
TVMVersion v2(main_header + 13);
this->version = v2;
size_t _len = (size_t)EnsureInt(stream);
char table_name[4];
for (size_t i = 0; i < _len; i++) {
Ensure(stream, (uint8_t *)table_name, sizeof(table_name));
size_t tableLen = (size_t)EnsureInt(stream);
if (strncmp(table_name, "NAME", 4) == 0) {
this->name = GetString(stream);
} else if (strncmp(table_name, "INFO", 4) == 0) {
this->info = GetString(stream);
} else if (strncmp(table_name, "DEPS", 4) == 0) // dependencies
{
std::string name = GetString(stream);
uint8_t version_bytes[5];
Ensure(stream, version_bytes, sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
this->dependencies.push_back(
std::pair<std::string, TVMVersion>(name, depVersion));
} else if (strncmp(table_name, "TOOL", 4) ==
0) // compile tools (for package manager)
{
std::string name = GetString(stream);
uint8_t version_bytes[5];
Ensure(stream, version_bytes, sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
this->tools.push_back(
std::pair<std::string, TVMVersion>(name, depVersion));
} else if (strncmp(table_name, "RESO", 4) ==
0) // resources (using embed)
{
auto &data = this->resources.emplace_back(tableLen);
Ensure(stream, data.data(), data.size());
} else if (strncmp(table_name, "CHKS", 4) == 0 &&
gc != nullptr) // chunks
{
GCList ls(gc);
size_t chunkCount = (size_t)EnsureInt(stream);
for (size_t j = 0; j < chunkCount; j++) {
auto chunk = TFileChunk::Create(ls);
chunk->file = this;
size_t argCount = (size_t)EnsureInt(stream);
for (size_t k = 0; k < argCount; k++) {
chunk->args.push_back(GetString(stream));
}
size_t len = (size_t)EnsureInt(stream);
chunk->code.resize(len);
Ensure(stream, chunk->code.data(), len);
// reader.ReadIntoBuffer(chunk->code);
this->chunks.push_back(chunk);
}
} else if (strncmp(table_name, "FUNS", 4) == 0) // functions
{
size_t funLength = (size_t)EnsureInt(stream);
for (size_t j = 0; j < funLength; j++) {
std::vector<std::string> fnParts;
uint32_t fnPartsC = EnsureInt(stream);
for (uint32_t k = 0; k < fnPartsC; k++) {
fnParts.push_back(GetString(stream));
}
uint32_t fnNumber = EnsureInt(stream);
this->functions.push_back(
std::pair<std::vector<std::string>, uint32_t>(fnParts,
fnNumber));
}
} else if (strncmp(table_name, "STRS", 4) == 0) // strings
{
size_t strsLen = (size_t)EnsureInt(stream);
for (size_t j = 0; j < strsLen; j++) {
this->strings.push_back(EnsureString(stream));
}
} else if (strncmp(table_name, "ICON", 4) == 0) // icon
{
this->icon = (int32_t)EnsureInt(stream);
} else if (strncmp(table_name, "MACH", 4) == 0) // machine
{
std::string name = GetString(stream);
std::string howToGet = GetString(stream);
this->vms.push_back(
std::pair<std::string, std::string>(name, howToGet));
} else if (strncmp(table_name, "CLSS", 4) == 0) // classes
{
uint32_t clsCnt = EnsureInt(stream);
for (uint32_t j = 0; j < clsCnt; j++) {
TClass cls;
cls.documentation = GetString(stream);
uint32_t name_cnt = EnsureInt(stream);
for (uint32_t k = 0; k < name_cnt; k++) {
cls.name.push_back(GetString(stream));
}
name_cnt = EnsureInt(stream);
for (uint32_t k = 0; k < name_cnt; k++) {
cls.inherits.push_back(GetString(stream));
}
name_cnt = EnsureInt(stream);
for (uint32_t k = 0; k < name_cnt; k++) {
TClassEntry ent;
Ensure(stream, main_header, 1);
uint8_t sig = main_header[0];
ent.isAbstract = (sig & 0b00001000) != 0;
ent.isFunction = (sig & 0b00000100) == 0;
ent.modifier = (TClassModifier)(sig & 3);
ent.documentation = GetString(stream);
ent.name = GetString(stream);
uint32_t arglen = EnsureInt(stream);
for (uint32_t l = 0; l < arglen; l++)
ent.args.push_back(GetString(stream));
ent.chunkId = EnsureInt(stream);
cls.entry.push_back(ent);
}
this->classes.push_back(cls);
}
} else if (strncmp(table_name, "META", 4) == 0) // structured metadata
{
if (tableLen > 4) {
auto name = this->GetString(stream);
auto &data = this->metadata.emplace_back(
name, std::vector<uint8_t>(tableLen - 4));
Ensure(stream, data.second.data(), tableLen - 4);
} else
throw VMException("meta tag is not valid");
} else {
auto &data = this->sections.emplace_back(
std::string(table_name, 4), std::vector<uint8_t>(tableLen));
Ensure(stream, data.second.data(), tableLen);
}
}
}
} // namespace Tesses::CrossLang
+181 -218
View File
@@ -8,270 +8,233 @@
#include <unistd.h>
#endif
using namespace Tesses::Framework::Threading;
using namespace std::chrono;
namespace Tesses::CrossLang
{
namespace Tesses::CrossLang {
bool GC::IsRunning()
{
bool GC::IsRunning() {
bool run = this->running;
bool run = this->running;
return run;
}
GC::GC()
{
return run;
}
GC::GC() {}
TDictionary *CreateThread(GCList &ls, TCallable *callable, bool detached) {
}
TDictionary* CreateThread(GCList& ls, TCallable* callable,bool detached)
{
TDictionary *dict = TDictionary::Create(ls);
TDictionary* dict = TDictionary::Create(ls);
ThreadHandle* th = new ThreadHandle();
th->gc = ls.GetGC();
th->callable = callable;
th->hasInit=false;
th->hasReturned = false;
th->detached=detached;
ls.Add(th);
ls.GetGC()->Watch(th);
ls.GetGC()->BarrierBegin();
dict->SetValue("_internal", th);
dict->DeclareFunction(ls.GetGC(),"Join","Join thread",{},[th](GCList& _ls, std::vector<TObject> _args)-> TObject{
ThreadHandle *th = new ThreadHandle();
th->gc = ls.GetGC();
th->callable = callable;
th->hasInit = false;
th->hasReturned = false;
th->detached = detached;
ls.Add(th);
ls.GetGC()->Watch(th);
ls.GetGC()->BarrierBegin();
dict->SetValue("_internal", th);
dict->DeclareFunction(
ls.GetGC(), "Join", "Join thread", {},
[th](GCList &_ls, std::vector<TObject> _args) -> TObject {
th->thrd->Join();
delete th->thrd;
if(th->hasReturned)
{
if (th->hasReturned) {
_ls.GetGC()->BarrierBegin();
auto v = th->returnValue;
_ls.Add(v);
_ls.GetGC()->BarrierEnd();
return v;
return v;
}
return Undefined();
});
dict->DeclareFunction(ls.GetGC(), "Detach","Detach thread",{},[th](GCList& _ls, std::vector<TObject> _args)-> TObject{
dict->DeclareFunction(
ls.GetGC(), "Detach", "Detach thread", {},
[th](GCList &_ls, std::vector<TObject> _args) -> TObject {
_ls.GetGC()->BarrierBegin();
th->detached=true;
th->detached = true;
_ls.GetGC()->BarrierEnd();
return Undefined();
});
dict->DeclareFunction(ls.GetGC(),"getFinished","Get whether thread has finished",{},[th](GCList& _ls, std::vector<TObject> _args)-> TObject{
return (bool)(th->hasReturned==true);
dict->DeclareFunction(
ls.GetGC(), "getFinished", "Get whether thread has finished", {},
[th](GCList &_ls, std::vector<TObject> _args) -> TObject {
return (bool)(th->hasReturned == true);
});
ls.GetGC()->BarrierEnd();
th->thrd =new Thread([th]()->void {
std::shared_ptr<GC> gc=th->gc;
GCList ls(gc);
ls.Add(th);
th->hasInit=true;
TObject cb = th->callable->Call(ls,{});
gc->BarrierBegin();
th->returnValue=cb;
gc->BarrierEnd();
th->hasReturned=true;
});
while(!th->hasInit);
return dict;
}
void GC::Start()
{
ls.GetGC()->BarrierEnd();
th->thrd = new Thread([th]() -> void {
std::shared_ptr<GC> gc = th->gc;
GCList ls(gc);
ls.Add(th);
th->hasInit = true;
TObject cb = th->callable->Call(ls, {});
gc->BarrierBegin();
th->returnValue = cb;
gc->BarrierEnd();
th->hasReturned = true;
});
while (!th->hasInit)
;
return dict;
}
void GC::Start() {
this->tpool=new Tesses::Framework::Lazy<Tesses::Framework::Threading::ThreadPool*>([]()->Tesses::Framework::Threading::ThreadPool*{
auto threads = Tesses::Framework::Threading::ThreadPool::GetNumberOfCores();
if(threads < 4) threads=4;
this->tpool = new Tesses::Framework::Lazy<
Tesses::Framework::Threading::ThreadPool *>(
[]() -> Tesses::Framework::Threading::ThreadPool * {
auto threads =
Tesses::Framework::Threading::ThreadPool::GetNumberOfCores();
if (threads < 4)
threads = 4;
return new Tesses::Framework::Threading::ThreadPool(threads);
},[](Tesses::Framework::Threading::ThreadPool* p)->void{delete p;});
this->mtx=new Mutex();
this->running = true;
this->thrd = new Thread([this]()->void {
std::chrono::time_point<std::chrono::system_clock> last_frame, this_frame;
},
[](Tesses::Framework::Threading::ThreadPool *p) -> void { delete p; });
this->mtx = new Mutex();
this->running = true;
this->thrd = new Thread([this]() -> void {
std::chrono::time_point<std::chrono::system_clock> last_frame,
this_frame;
this_frame = system_clock::now();
last_frame = this_frame;
while(this->IsRunning())
{
while (this->IsRunning()) {
this_frame = system_clock::now();
if((this_frame - last_frame) > 10s)
{
if ((this_frame - last_frame) > 10s) {
last_frame = this_frame;
this->Collect();
}
#if defined(_WIN32)
#if defined(_WIN32)
Sleep(100);
#else
#else
usleep(100000);
#endif
#endif
}
GC::Collect();
});
}
});
}
bool GC::UsingNullThreads()
{
return false;
}
bool GC::UsingNullThreads() { return false; }
void GC::BarrierBegin()
{
this->mtx->Lock();
}
void GC::BarrierEnd()
{
this->mtx->Unlock();
}
void GC::Watch(TObject obj)
{
if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto _item=std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for(auto item : this->objects)
{
if(item == _item) {
this->BarrierEnd();
return;
}
}
this->objects.push_back(_item);
this->BarrierEnd();
}
}
void GC::Mark(TObject obj)
{
if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto _item=std::get<THeapObjectHolder>(obj).obj;
_item->Mark();
}
}
void GC::Unwatch(TObject obj)
{
if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto _item=std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for(auto index = this->objects.begin();index<this->objects.end();index++)
{
if(*index == _item)
{
this->objects.erase(index);
continue;
}
}
this->BarrierEnd();
}
}
void GC::SetRoot(TObject obj)
{
if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto _item=std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for(auto item : this->roots)
{
if(item == _item) {
this->BarrierEnd();
return;
}
}
this->roots.push_back(_item);
this->BarrierEnd();
}
}
Tesses::Framework::Threading::ThreadPool* GC::GetPool()
{
return this->tpool->GetValue();
}
void GC::UnsetRoot(TObject obj)
{
if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto _item=std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for(auto index = this->roots.begin();index<this->roots.end();index++)
{
if(*index == _item)
{
this->roots.erase(index);
continue;
}
}
this->BarrierEnd();
}
}
GC::~GC()
{
GC::BarrierBegin();
this->roots.clear();
GC::BarrierEnd();
this->running=false;
this->thrd->Join();
delete this->thrd;
for(auto item : objects) delete item;
delete this->tpool;
delete this->mtx;
}
void GC::RegisterEverythingCallback(std::function<void(std::shared_ptr<GC> gc, TRootEnvironment* env)> cb)
{
this->register_everything.push_back(cb);
}
void GC::RegisterEverything(TRootEnvironment* env)
{
for(auto item : this->register_everything)
item(this->shared_from_this(),env);
}
void GC::Collect()
{
void GC::BarrierBegin() { this->mtx->Lock(); }
void GC::BarrierEnd() { this->mtx->Unlock(); }
void GC::Watch(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for(auto item : this->objects)
{
item->marked=false;
}
for(auto item : this->roots)
{
item->Mark();
}
for(auto index = this->objects.begin();index < this->objects.end();index++)
{
THeapObject* o = *index;
if(!o->marked)
{
delete o;
this->objects.erase(index);
index--;
for (auto item : this->objects) {
if (item == _item) {
this->BarrierEnd();
return;
}
}
this->objects.push_back(_item);
this->BarrierEnd();
}
}
void GC::Mark(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj;
_item->Mark();
}
}
void GC::Unwatch(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for (auto index = this->objects.begin();
index != this->objects.end();) {
if (*index == _item) {
index = this->objects.erase(index);
continue;
}
index++;
}
this->BarrierEnd();
}
};
}
void GC::SetRoot(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for (auto item : this->roots) {
if (item == _item) {
this->BarrierEnd();
return;
}
}
this->roots.push_back(_item);
this->BarrierEnd();
}
}
Tesses::Framework::Threading::ThreadPool *GC::GetPool() {
return this->tpool->GetValue();
}
void GC::UnsetRoot(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin();
for (auto index = this->roots.begin(); index != this->roots.end();) {
if (*index == _item) {
index = this->roots.erase(index);
continue;
}
index++;
}
this->BarrierEnd();
}
}
GC::~GC() {
GC::BarrierBegin();
this->roots.clear();
GC::BarrierEnd();
this->running = false;
this->thrd->Join();
delete this->thrd;
for (auto item : objects)
delete item;
delete this->tpool;
delete this->mtx;
}
void GC::RegisterEverythingCallback(
std::function<void(std::shared_ptr<GC> gc, TRootEnvironment *env)> cb) {
this->register_everything.push_back(cb);
}
void GC::RegisterEverything(TRootEnvironment *env) {
for (auto item : this->register_everything)
item(this->shared_from_this(), env);
}
void GC::Collect() {
this->BarrierBegin();
for (auto item : this->objects) {
item->marked = false;
}
for (auto item : this->roots) {
item->Mark();
}
for (auto index = this->objects.begin(); index != this->objects.end();
index++) {
THeapObject *o = *index;
if (!o->marked) {
delete o;
this->objects.erase(index);
index--;
}
}
this->BarrierEnd();
}
}; // namespace Tesses::CrossLang
+46 -60
View File
@@ -1,67 +1,53 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
GCList::GCList(std::shared_ptr<GC> gc)
{
gc->BarrierBegin();
this->gc = gc;
gc->SetRoot(this);
gc->BarrierEnd();
}
std::shared_ptr<GC> GCList::GetGC()
{
return this->gc;
}
void GCList::Remove(TObject obj)
{
if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto _item=std::get<THeapObjectHolder>(obj).obj;
this->gc->BarrierBegin();
for(auto index = this->items.begin();index<this->items.end();index++)
{
if(*index == _item)
{
this->items.erase(index);
continue;
}
}
this->gc->BarrierEnd();
}
}
void GCList::Add(TObject obj)
{
namespace Tesses::CrossLang {
GCList::GCList(std::shared_ptr<GC> gc) {
gc->BarrierBegin();
this->gc = gc;
gc->SetRoot(this);
gc->BarrierEnd();
}
if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto _item=std::get<THeapObjectHolder>(obj).obj;
this->gc->BarrierBegin();
for(auto item : this->items)
{
if(item == _item) {
this->gc->BarrierEnd();
return;
}
std::shared_ptr<GC> GCList::GetGC() { return this->gc; }
void GCList::Remove(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj;
this->gc->BarrierBegin();
for (auto index = this->items.begin(); index != this->items.end();
index++) {
if (*index == _item) {
this->items.erase(index);
continue;
}
this->items.push_back(_item);
this->gc->BarrierEnd();
}
}
void GCList::Mark()
{
this->marked=true;
for(auto item : this->items)
{
item->Mark();
}
}
GCList::~GCList()
{
gc->BarrierBegin();
this->gc->UnsetRoot(this);
gc->BarrierEnd();
this->gc->BarrierEnd();
}
}
void GCList::Add(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj;
this->gc->BarrierBegin();
for (auto item : this->items) {
if (item == _item) {
this->gc->BarrierEnd();
return;
}
}
this->items.push_back(_item);
this->gc->BarrierEnd();
}
}
void GCList::Mark() {
this->marked = true;
for (auto item : this->items) {
item->Mark();
}
}
GCList::~GCList() {
gc->BarrierBegin();
this->gc->UnsetRoot(this);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang
+2833 -3344
View File
File diff suppressed because it is too large Load Diff
+256 -258
View File
@@ -1,260 +1,258 @@
#if defined(VM_OPCODE_TABLE_INLINE)
static opcode opcodes[256]={
&InterperterThread::Add,
&InterperterThread::Sub,
&InterperterThread::Times,
&InterperterThread::Divide,
&InterperterThread::Mod,
&InterperterThread::LShift,
&InterperterThread::RShift,
&InterperterThread::BOr,
&InterperterThread::BAnd,
&InterperterThread::BNot,
&InterperterThread::Lt,
&InterperterThread::Gt,
&InterperterThread::Lte,
&InterperterThread::Gte,
&InterperterThread::Eq,
&InterperterThread::NEq,
&InterperterThread::LNot,
&InterperterThread::Neg,
&InterperterThread::XOr,
&InterperterThread::Pop,
&InterperterThread::Dup,
&InterperterThread::Nop,
&InterperterThread::PushClosure,
&InterperterThread::CreateDictionary,
&InterperterThread::CreateArray,
&InterperterThread::AppendList,
&InterperterThread::AppendDictionary,
&InterperterThread::PushResource,
&InterperterThread::PushLong,
&InterperterThread::PushChar,
&InterperterThread::PushDouble,
&InterperterThread::PushString,
&InterperterThread::PushNull,
&InterperterThread::PushUndefined,
&InterperterThread::ScopeBegin,
&InterperterThread::ScopeEnd,
&InterperterThread::ScopeEndTimes,
&InterperterThread::PushFalse,
&InterperterThread::PushTrue,
&InterperterThread::SetVariable,
&InterperterThread::GetVariable,
&InterperterThread::DeclareVariable,
&InterperterThread::SetField,
&InterperterThread::GetField,
&InterperterThread::ExecuteFunction,
&InterperterThread::ExecuteMethod,
&InterperterThread::Return,
&InterperterThread::JumpConditional,
&InterperterThread::Jump,
&InterperterThread::JumpUndefined,
&InterperterThread::Defer,
&InterperterThread::TryCatch,
&InterperterThread::Throw,
&InterperterThread::PushScopelessClosure,
&InterperterThread::Yield,
&InterperterThread::PushRootPath,
&InterperterThread::PushRelativePath,
&InterperterThread::Breakpoint,
&InterperterThread::PushBreak,
&InterperterThread::PushContinue,
&InterperterThread::JumpIfBreak,
&InterperterThread::JumpIfContinue,
&InterperterThread::JumpIfDefined,
&InterperterThread::DeclareConstVariable,
&InterperterThread::LineInfo,
&InterperterThread::PushResourceStream,
&InterperterThread::PushResourceDirectory,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal
};
static opcode opcodes[256] = {&InterperterThread::Add,
&InterperterThread::Sub,
&InterperterThread::Times,
&InterperterThread::Divide,
&InterperterThread::Mod,
&InterperterThread::LShift,
&InterperterThread::RShift,
&InterperterThread::BOr,
&InterperterThread::BAnd,
&InterperterThread::BNot,
&InterperterThread::Lt,
&InterperterThread::Gt,
&InterperterThread::Lte,
&InterperterThread::Gte,
&InterperterThread::Eq,
&InterperterThread::NEq,
&InterperterThread::LNot,
&InterperterThread::Neg,
&InterperterThread::XOr,
&InterperterThread::Pop,
&InterperterThread::Dup,
&InterperterThread::Nop,
&InterperterThread::PushClosure,
&InterperterThread::CreateDictionary,
&InterperterThread::CreateArray,
&InterperterThread::AppendList,
&InterperterThread::AppendDictionary,
&InterperterThread::PushResource,
&InterperterThread::PushLong,
&InterperterThread::PushChar,
&InterperterThread::PushDouble,
&InterperterThread::PushString,
&InterperterThread::PushNull,
&InterperterThread::PushUndefined,
&InterperterThread::ScopeBegin,
&InterperterThread::ScopeEnd,
&InterperterThread::ScopeEndTimes,
&InterperterThread::PushFalse,
&InterperterThread::PushTrue,
&InterperterThread::SetVariable,
&InterperterThread::GetVariable,
&InterperterThread::DeclareVariable,
&InterperterThread::SetField,
&InterperterThread::GetField,
&InterperterThread::ExecuteFunction,
&InterperterThread::ExecuteMethod,
&InterperterThread::Return,
&InterperterThread::JumpConditional,
&InterperterThread::Jump,
&InterperterThread::JumpUndefined,
&InterperterThread::Defer,
&InterperterThread::TryCatch,
&InterperterThread::Throw,
&InterperterThread::PushScopelessClosure,
&InterperterThread::Yield,
&InterperterThread::PushRootPath,
&InterperterThread::PushRelativePath,
&InterperterThread::Breakpoint,
&InterperterThread::PushBreak,
&InterperterThread::PushContinue,
&InterperterThread::JumpIfBreak,
&InterperterThread::JumpIfContinue,
&InterperterThread::JumpIfDefined,
&InterperterThread::DeclareConstVariable,
&InterperterThread::LineInfo,
&InterperterThread::PushResourceStream,
&InterperterThread::PushResourceDirectory,
&InterperterThread::PushPrivateExpression,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal};
#endif