mirror of
https://git.tesses.org/tesses50/crosslang.git
synced 2026-08-02 08:35:32 +00:00
Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user