mirror of
https://git.tesses.org/tesses50/crosslang.git
synced 2026-08-02 00:25:32 +00:00
Add uuid support
This commit is contained in:
769
src/vm/bc/getfield.cpp
Normal file
769
src/vm/bc/getfield.cpp
Normal file
@@ -0,0 +1,769 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||
#include "TessesFramework/Streams/ByteReader.hpp"
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <variant>
|
||||
namespace Tesses::CrossLang {
|
||||
bool InterperterThread::GetField(GC* gc)
|
||||
{
|
||||
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
|
||||
|
||||
if(!cse.empty())
|
||||
{
|
||||
auto stk = cse.back();
|
||||
GCList ls(gc);
|
||||
TObject _key = stk->Pop(ls);
|
||||
|
||||
|
||||
TObject instance = stk->Pop(ls);
|
||||
|
||||
if(!std::holds_alternative<std::string>(_key))
|
||||
{
|
||||
stk->Push(gc,Undefined());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string key = std::get<std::string>(_key);
|
||||
|
||||
|
||||
if(std::holds_alternative<std::string>(instance))
|
||||
{
|
||||
std::string str = std::get<std::string>(instance);
|
||||
|
||||
if(key == "Count" || key == "Length")
|
||||
{
|
||||
int64_t len = (int64_t)str.size();
|
||||
if(len < 0) len = 0;
|
||||
|
||||
cse.back()->Push(gc, len);
|
||||
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 tmpFS=std::dynamic_pointer_cast<Tesses::Framework::Filesystem::TempFS>(vfs);
|
||||
if(tmpFS)
|
||||
{
|
||||
if(key == "TempDirectoryName")
|
||||
{
|
||||
|
||||
cse.back()->Push(gc,tmpFS->TempDirectoryName());
|
||||
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")
|
||||
{
|
||||
cse.back()->Push(gc, stringWriter->GetString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(key == "NewLine")
|
||||
{
|
||||
cse.back()->Push(gc,writer->newline);
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc,Undefined());
|
||||
return false;
|
||||
}
|
||||
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::ByteReader>>(instance))
|
||||
{
|
||||
auto br = std::get<std::shared_ptr<Tesses::Framework::Streams::ByteReader>>(instance);
|
||||
if(key == "Stream")
|
||||
{
|
||||
cse.back()->Push(gc,br->GetStream());
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc,Undefined());
|
||||
return false;
|
||||
}
|
||||
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::ByteWriter>>(instance))
|
||||
{
|
||||
auto bw = std::get<std::shared_ptr<Tesses::Framework::Streams::ByteWriter>>(instance);
|
||||
if(key == "Stream")
|
||||
{
|
||||
|
||||
cse.back()->Push(gc,bw->GetStream());
|
||||
return false;
|
||||
}
|
||||
cse.back()->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);
|
||||
if(strm != nullptr)
|
||||
{
|
||||
auto netStrm = std::dynamic_pointer_cast<Tesses::Framework::Streams::NetworkStream>(strm);
|
||||
|
||||
if(key == "CanRead")
|
||||
{
|
||||
|
||||
|
||||
cse.back()->Push(gc, strm->CanRead());
|
||||
return false;
|
||||
}
|
||||
if(key == "CanWrite")
|
||||
{
|
||||
|
||||
cse.back()->Push(gc, strm->CanWrite());
|
||||
return false;
|
||||
}
|
||||
if(key == "CanSeek")
|
||||
{
|
||||
|
||||
|
||||
cse.back()->Push(gc, strm->CanSeek());
|
||||
return false;
|
||||
}
|
||||
if(key == "EndOfStream")
|
||||
{
|
||||
|
||||
cse.back()->Push(gc, strm->EndOfStream());
|
||||
return false;
|
||||
}
|
||||
if(key == "Length")
|
||||
{
|
||||
|
||||
cse.back()->Push(gc, strm->GetLength());
|
||||
return false;
|
||||
}
|
||||
if(key == "Position")
|
||||
{
|
||||
|
||||
cse.back()->Push(gc, strm->GetPosition());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(netStrm != nullptr)
|
||||
{
|
||||
if(key == "Port")
|
||||
{
|
||||
cse.back()->Push(gc, netStrm->GetPort());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cse.back()->Push(gc, Undefined());
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
if(std::holds_alternative<TVMVersion>(instance))
|
||||
{
|
||||
TVMVersion& version = std::get<TVMVersion>(instance);
|
||||
if(key == "Major")
|
||||
{
|
||||
stk->Push(gc, (int64_t)version.Major());
|
||||
return false;
|
||||
}
|
||||
if(key == "Minor")
|
||||
{
|
||||
stk->Push(gc, (int64_t)version.Minor());
|
||||
return false;
|
||||
}
|
||||
if(key == "Patch")
|
||||
{
|
||||
stk->Push(gc, (int64_t)version.Patch());
|
||||
return false;
|
||||
}
|
||||
if(key == "Build")
|
||||
{
|
||||
stk->Push(gc, (int64_t)version.Build());
|
||||
return false;
|
||||
}
|
||||
if(key == "VersionInt")
|
||||
{
|
||||
stk->Push(gc,(int64_t)version.AsLong());
|
||||
return false;
|
||||
}
|
||||
if(key == "Stage")
|
||||
{
|
||||
switch(version.VersionStage())
|
||||
{
|
||||
case TVMVersionStage::DevVersion:
|
||||
stk->Push(gc,"dev");
|
||||
break;
|
||||
case TVMVersionStage::AlphaVersion:
|
||||
stk->Push(gc,"alpha");
|
||||
break;
|
||||
case TVMVersionStage::BetaVersion:
|
||||
stk->Push(gc,"beta");
|
||||
break;
|
||||
case TVMVersionStage::ProductionVersion:
|
||||
stk->Push(gc,"prod");
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
stk->Push(gc, Undefined());
|
||||
return false;
|
||||
}
|
||||
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance))
|
||||
{
|
||||
auto time = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance);
|
||||
if(key == "Days")
|
||||
{
|
||||
stk->Push(gc, (int64_t)time->Days());
|
||||
return false;
|
||||
}
|
||||
if(key == "Hours")
|
||||
{
|
||||
stk->Push(gc, (int64_t)time->Hours());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(key == "Minutes")
|
||||
{
|
||||
stk->Push(gc, (int64_t)time->Minutes());
|
||||
return false;
|
||||
}
|
||||
if(key == "Seconds")
|
||||
{
|
||||
stk->Push(gc, (int64_t)time->Seconds());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(key == "TotalHours")
|
||||
{
|
||||
stk->Push(gc, time->TotalHours());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(key == "TotalMinutes")
|
||||
{
|
||||
stk->Push(gc, time->TotalMinutes());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(key == "TotalSeconds")
|
||||
{
|
||||
stk->Push(gc, time->TotalSeconds());
|
||||
return false;
|
||||
}
|
||||
|
||||
stk->Push(gc, Undefined());
|
||||
return false;
|
||||
}
|
||||
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance))
|
||||
{
|
||||
auto& date = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance);
|
||||
if(key == "IsLocal")
|
||||
{
|
||||
stk->Push(gc, date->IsLocal());
|
||||
return false;
|
||||
}
|
||||
if(key == "Year")
|
||||
{
|
||||
stk->Push(gc, (int64_t)date->Year());
|
||||
return false;
|
||||
}
|
||||
if(key == "Month")
|
||||
{
|
||||
stk->Push(gc, (int64_t)date->Month());
|
||||
return false;
|
||||
}
|
||||
if(key == "Day")
|
||||
{
|
||||
stk->Push(gc, (int64_t)date->Day());
|
||||
return false;
|
||||
}
|
||||
if(key == "Hour")
|
||||
{
|
||||
stk->Push(gc, (int64_t)date->Hour());
|
||||
return false;
|
||||
}
|
||||
if(key == "Minute")
|
||||
{
|
||||
stk->Push(gc, (int64_t)date->Minute());
|
||||
return false;
|
||||
}
|
||||
if(key == "Second")
|
||||
{
|
||||
stk->Push(gc, (int64_t)date->Second());
|
||||
return false;
|
||||
}
|
||||
if(key == "DayOfWeek")
|
||||
{
|
||||
stk->Push(gc, (int64_t)date->DayOfWeek());
|
||||
return false;
|
||||
}
|
||||
|
||||
stk->Push(gc, Undefined());
|
||||
return false;
|
||||
}
|
||||
if(std::holds_alternative<THeapObjectHolder>(instance))
|
||||
{
|
||||
auto obj = std::get<THeapObjectHolder>(instance).obj;
|
||||
auto bA = dynamic_cast<TByteArray*>(obj);
|
||||
auto list = dynamic_cast<TList*>(obj);
|
||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||
auto dynList = dynamic_cast<TDynamicList*>(obj);
|
||||
auto tcallable = dynamic_cast<TCallable*>(obj);
|
||||
auto closure = dynamic_cast<TClosure*>(obj);
|
||||
auto externalMethod = dynamic_cast<TExternalMethod*>(obj);
|
||||
auto ittr = dynamic_cast<TEnumerator*>(obj);
|
||||
|
||||
auto callstackEntry = dynamic_cast<CallStackEntry*>(obj);
|
||||
auto file = dynamic_cast<TFile*>(obj);
|
||||
auto chunk = dynamic_cast<TFileChunk*>(obj);
|
||||
auto natObj = dynamic_cast<TNativeObject*>(obj);
|
||||
auto cls = dynamic_cast<TClassObject*>(obj);
|
||||
auto aarray = dynamic_cast<TAssociativeArray*>(obj);
|
||||
auto task = dynamic_cast<TTask*>(obj);
|
||||
if(task != nullptr)
|
||||
{
|
||||
if(key == "IsCompleted")
|
||||
{
|
||||
cse.back()->Push(gc,task->IsCompleted());
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc,Undefined());
|
||||
return false;
|
||||
}
|
||||
if(aarray != nullptr)
|
||||
{
|
||||
if(key == "Count" || key == "Length")
|
||||
{
|
||||
cse.back()->Push(gc,aarray->Count());
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc, Undefined());
|
||||
return false;
|
||||
}
|
||||
else if(cls != nullptr)
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
auto obj=cls->GetValue(cse.back()->callable->className,"get"+key);
|
||||
gc->BarrierEnd();
|
||||
TClosure* clos;
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(obj,clos))
|
||||
{
|
||||
this->AddCallStackEntry(ls,clos,{});
|
||||
return true;
|
||||
}
|
||||
else if(GetObjectHeap(obj,callable))
|
||||
{
|
||||
cse.back()->Push(gc,callable->Call(ls,{}));
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc,cls->GetValue(cse.back()->callable->className,key));
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
if(natObj != nullptr)
|
||||
{
|
||||
cse.back()->Push(gc,natObj->CallMethod(ls,"get"+key,{}));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(file != nullptr)
|
||||
{
|
||||
if(key == "Version")
|
||||
{
|
||||
cse.back()->Push(gc,file->version);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Name")
|
||||
{
|
||||
cse.back()->Push(gc,file->name);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Info")
|
||||
{
|
||||
cse.back()->Push(gc, file->info);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Dependencies")
|
||||
{
|
||||
auto list = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto item : file->dependencies)
|
||||
{
|
||||
auto res = TDictionary::Create(ls);
|
||||
res->SetValue("Name", item.first);
|
||||
res->SetValue("Version", item.second);
|
||||
list->Add(res);
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
cse.back()->Push(gc, list);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Tools")
|
||||
{
|
||||
auto list = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto item : file->tools)
|
||||
{
|
||||
auto res = TDictionary::Create(ls);
|
||||
res->SetValue("Name", item.first);
|
||||
res->SetValue("Version", item.second);
|
||||
list->Add(res);
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
cse.back()->Push(gc, list);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Strings")
|
||||
{
|
||||
auto list = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto item : file->name)
|
||||
{
|
||||
list->Add(item);
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
|
||||
cse.back()->Push(gc, list);
|
||||
return false;
|
||||
}
|
||||
else if(key == "MetadataCount")
|
||||
{
|
||||
|
||||
cse.back()->Push(gc, (int64_t)file->metadata.size());
|
||||
return false;
|
||||
}
|
||||
else if(key == "Metadata")
|
||||
{
|
||||
TList* meta = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(size_t i = 0; i < file->metadata.size(); i++)
|
||||
{
|
||||
meta->Add(
|
||||
TDictionary::Create(ls,
|
||||
{
|
||||
TDItem("Name", file->metadata[i].first),
|
||||
TDItem("Index",(int64_t)i)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
|
||||
cse.back()->Push(gc, meta);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Sections")
|
||||
{
|
||||
TList* sections = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto& item : file->sections)
|
||||
{
|
||||
TByteArray* ba = TByteArray::Create(ls);
|
||||
ba->data = item.second;
|
||||
sections->Add(TDictionary::Create(ls,{
|
||||
TDItem("Name", item.first),
|
||||
TDItem("Data", ba)
|
||||
}));
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
|
||||
cse.back()->Push(gc, sections);
|
||||
return false;
|
||||
}
|
||||
else if(key == "SupportedVMs")
|
||||
{
|
||||
TList* supported = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
if(file->vms.empty())
|
||||
{
|
||||
supported->Add(TDictionary::Create(ls,{
|
||||
TDItem("Name",std::string(VMName)),
|
||||
TDItem("HowToGet",std::string(VMHowToGet))
|
||||
}));
|
||||
}
|
||||
else {
|
||||
for(auto item : file->vms)
|
||||
supported->Add(TDictionary::Create(ls,{
|
||||
TDItem("Name",item.first),
|
||||
TDItem("HowToGet",item.second)
|
||||
}));
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
cse.back()->Push(gc, supported);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Chunks")
|
||||
{
|
||||
auto list = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto item : file->chunks)
|
||||
{
|
||||
list->Add(item);
|
||||
}
|
||||
|
||||
gc->BarrierEnd();
|
||||
|
||||
cse.back()->Push(gc, list);
|
||||
return false;
|
||||
}
|
||||
else if(key == "Classes")
|
||||
{
|
||||
auto list = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
|
||||
for(uint32_t i = 0; i < (uint32_t)file->classes.size(); i++)
|
||||
{
|
||||
list->Add(GetClassInfo(ls,file,i));
|
||||
}
|
||||
|
||||
cse.back()->Push(gc, list);
|
||||
gc->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
else if(key == "Functions")
|
||||
{
|
||||
auto list = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto& item : file->functions)
|
||||
{
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
if(!item.first.empty())
|
||||
dict->SetValue("Documentation", item.first[0]);
|
||||
TList* nameParts = TList::Create(ls);
|
||||
for(size_t i = 1; i < item.first.size(); i++)
|
||||
{
|
||||
nameParts->Add(item.first[i]);
|
||||
}
|
||||
dict->SetValue("NameParts", nameParts);
|
||||
dict->SetValue("ChunkId", (int64_t)item.second);
|
||||
|
||||
list->Add(dict);
|
||||
}
|
||||
|
||||
cse.back()->Push(gc, list);
|
||||
gc->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
else if(key == "Icon")
|
||||
{
|
||||
if(file->icon >= 0 && file->icon < file->resources.size())
|
||||
{
|
||||
TByteArray* ba = TByteArray::Create(ls);
|
||||
ba->data = file->resources[file->icon];
|
||||
cse.back()->Push(gc, ba);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
cse.back()->Push(gc, nullptr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
cse.back()->Push(gc, Undefined());
|
||||
return false;
|
||||
}
|
||||
if(chunk != nullptr)
|
||||
{
|
||||
if(key == "Arguments")
|
||||
{
|
||||
auto myargs = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto item : chunk->args)
|
||||
{
|
||||
myargs->Add(item);
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
cse.back()->Push(gc, myargs);
|
||||
return false;
|
||||
}
|
||||
if(key == "Code")
|
||||
{
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = chunk->code;
|
||||
cse.back()->Push(gc, ba);
|
||||
return false;
|
||||
}
|
||||
if(key == "File")
|
||||
{
|
||||
cse.back()->Push(gc, chunk->file);
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc, Undefined());
|
||||
return false;
|
||||
}
|
||||
if(callstackEntry != nullptr)
|
||||
{
|
||||
if(key == "IP")
|
||||
{
|
||||
cse.back()->Push(gc, (int64_t)callstackEntry->ip);
|
||||
return false;
|
||||
}
|
||||
if(key == "IsDone")
|
||||
{
|
||||
cse.back()->Push(gc, callstackEntry->ip >= callstackEntry->callable->closure->code.size());
|
||||
return false;
|
||||
}
|
||||
if(key == "Closure")
|
||||
{
|
||||
cse.back()->Push(gc, callstackEntry->callable);
|
||||
return false;
|
||||
}
|
||||
if(key == "StackEmpty")
|
||||
{
|
||||
cse.back()->Push(gc, callstackEntry->stack.empty());
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc,Undefined());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(ittr != nullptr)
|
||||
{
|
||||
if(key == "Current")
|
||||
{
|
||||
cse.back()->Push(gc, ittr->GetCurrent(ls));
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc, Undefined());
|
||||
return false;
|
||||
}
|
||||
if(closure != nullptr)
|
||||
{
|
||||
if(key == "Arguments")
|
||||
{
|
||||
GCList ls2(gc);
|
||||
TList* ls = TList::Create(ls2);
|
||||
for(auto arg : closure->closure->args)
|
||||
{
|
||||
ls->Add(arg);
|
||||
}
|
||||
cse.back()->Push(gc,ls);
|
||||
return false;
|
||||
}
|
||||
if(key == "File")
|
||||
{
|
||||
cse.back()->Push(gc,closure->file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(externalMethod != nullptr)
|
||||
{
|
||||
if(key == "Arguments")
|
||||
{
|
||||
GCList ls2(gc);
|
||||
TList* ls = TList::Create(ls2);
|
||||
for(auto arg : externalMethod->args)
|
||||
{
|
||||
ls->Add(arg);
|
||||
}
|
||||
cse.back()->Push(gc,ls);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(tcallable != nullptr)
|
||||
{
|
||||
if(key == "Documentation")
|
||||
{
|
||||
cse.back()->Push(gc, tcallable->documentation);
|
||||
return false;
|
||||
}
|
||||
if(key == "Tag")
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
cse.back()->Push(gc, tcallable->tag);
|
||||
gc->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc,Undefined());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(bA != nullptr)
|
||||
{
|
||||
if(key == "Count" || key == "Length")
|
||||
{
|
||||
int64_t len = (int64_t)bA->data.size();
|
||||
if(len < 0) len = 0;
|
||||
|
||||
stk->Push(gc, len);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(list != nullptr)
|
||||
{
|
||||
if(key == "Count" || key == "Length")
|
||||
{
|
||||
int64_t len = list->Count();
|
||||
if(len < 0) len = 0;
|
||||
|
||||
stk->Push(gc, len);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(dynList != nullptr)
|
||||
{
|
||||
if(key == "Count" || key == "Length")
|
||||
{
|
||||
int64_t len = dynList->Count(ls);
|
||||
if(len < 0) len = 0;
|
||||
|
||||
stk->Push(gc, len);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(dynDict != nullptr)
|
||||
{
|
||||
if(dynDict->MethodExists(ls,"get" + key))
|
||||
{
|
||||
cse.back()->Push(gc,dynDict->CallMethod(ls,"get" + key, {}));
|
||||
}
|
||||
else
|
||||
{
|
||||
cse.back()->Push(gc, dynDict->GetField(ls,key));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(dict != nullptr)
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
TObject fn = dict->GetValue("get" + key);
|
||||
gc->BarrierEnd();
|
||||
if(std::holds_alternative<THeapObjectHolder>(fn) && dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj) != nullptr)
|
||||
{
|
||||
return InvokeOne(ls,fn, dict);
|
||||
}
|
||||
else
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
fn = dict->GetValue(key);
|
||||
stk->Push(gc, fn);
|
||||
gc->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
stk->Push(gc, Undefined());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user