Add embeddir finally and embedstrm

This commit is contained in:
2025-12-17 06:07:27 -06:00
parent deb492b8c4
commit c37b26af14
13 changed files with 484 additions and 25 deletions

View File

@@ -154,6 +154,7 @@ src/runtime_methods/path.cpp
src/runtime_methods/env.cpp
src/runtime_methods/process.cpp
src/runtime_methods/helpers.cpp
src/types/embed.cpp
src/types/async.cpp
src/types/associativearray.cpp
src/types/any.cpp

View File

@@ -662,7 +662,9 @@ typedef enum {
JMPIFCONTINUE,
JMPIFDEFINED,
DECLARECONSTVARIABLE,
LINEINFO
LINEINFO,
PUSHRESOURCESTREAM,
PUSHRESOUURCEDIR
} Instruction;
/**
* @brief Base type for bytecode instruction
@@ -762,6 +764,13 @@ class EmbedInstruction : public ByteCodeInstruction {
size_t Size();
void Write(std::vector<uint8_t>& data);
};
class EmbedStreamInstruction : public ByteCodeInstruction {
public:
uint32_t n;
EmbedStreamInstruction(uint32_t n);
size_t Size();
void Write(std::vector<uint8_t>& data);
};
class ClosureInstruction : public ByteCodeInstruction {
public:
@@ -867,6 +876,7 @@ class CodeGen {
void GenNode(std::vector<ByteCodeInstruction*>& instructions, SyntaxNode n,int32_t scope, int32_t contscope, int32_t brkscope, int32_t contI, int32_t brkI);
void GenPop(std::vector<ByteCodeInstruction*>& instrs,SyntaxNode n);
public:
std::shared_ptr<Tesses::Framework::Filesystem::VFS> embedFS;
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
TVMVersion version;
@@ -874,7 +884,7 @@ class CodeGen {
std::string info;
std::string icon;
void GenRoot(SyntaxNode n);
void Save(std::shared_ptr<Tesses::Framework::Filesystem::VFS> embedFS,std::shared_ptr<Tesses::Framework::Streams::Stream> output);
void Save(std::shared_ptr<Tesses::Framework::Streams::Stream> output);
~CodeGen();
};
/**
@@ -883,10 +893,20 @@ class CodeGen {
*/
constexpr std::string_view HtmlRootExpression = "htmlRootExpression";
/**
* @brief an intrinsic function that embeads a resource from the filename based on the constant string argument
* @brief an intrinsic function that embeds a resource from the filename based on the constant string argument
*
*/
constexpr std::string_view EmbedExpression = "embedExpression";
/**
* @brief an intrinsic function that embeds a resource as a stream from the filename based on the constant string argument
*
*/
constexpr std::string_view EmbedStreamExpression = "embedStreamExpression";
/**
* @brief an intrinsic function that embeds a resource directory from the directory name based on the constant string argument
*
*/
constexpr std::string_view EmbedDirectoryExpression = "embedDirectoryExpression";
/**
* @brief Negative operator -EXPR
*
@@ -2061,6 +2081,8 @@ class GC {
~TObjectStream();
};
class TObjectHttpServer : public Tesses::Framework::Http::IHttpServer
{
public:
@@ -2279,6 +2301,8 @@ class GC {
bool JumpIfBreak(GC* gc);
bool JumpIfContinue(GC* gc);
bool LineInfo(GC* gc);
bool PushResourceStream(GC* gc);
bool PushResourceDirectory(GC* gc);
public:
static InterperterThread* Create(GCList* ls);
static InterperterThread* Create(GCList& ls);
@@ -2543,4 +2567,39 @@ class GC {
std::shared_ptr<Tesses::Framework::Http::IHttpServer> ToHttpServer(GC* gc,TObject obj);
class EmbedStream : public Tesses::Framework::Streams::Stream
{
size_t offset;
MarkedTObject file;
uint32_t resource;
public:
EmbedStream(GC* gc, TFile* file, uint32_t resource);
bool CanRead();
bool CanSeek();
bool EndOfStream();
size_t Read(uint8_t* buff, size_t len);
int64_t GetPosition();
int64_t GetLength();
void Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence);
};
class EmbedDirectory : public Tesses::Framework::Filesystem::VFS
{
MarkedTObject dir;
TObject getEntry(Tesses::Framework::Filesystem::VFSPath path);
public:
EmbedDirectory(GC* gc, TDictionary* dict);
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode);
void CreateDirectory(Tesses::Framework::Filesystem::VFSPath path);
void DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path);
bool RegularFileExists(Tesses::Framework::Filesystem::VFSPath path);
bool DirectoryExists(Tesses::Framework::Filesystem::VFSPath path);
void DeleteFile(Tesses::Framework::Filesystem::VFSPath path);
Tesses::Framework::Filesystem::VFSPathEnumerator EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path);
void MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest);
std::string VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path);
Tesses::Framework::Filesystem::VFSPath SystemToVFSPath(std::string path);
};
};

View File

@@ -83,6 +83,18 @@ namespace Tesses::CrossLang {
}
};
class PushResourceStreamChunkInstruction : public ChunkInstruction {
public:
PushResourceStreamChunkInstruction(std::string v) : value(v)
{}
std::string value;
size_t Size()
{
return 5;
}
};
class LabelChunkInstruction : public ChunkInstruction {
public:
LabelChunkInstruction(std::string lbl) : lbl(lbl)
@@ -285,6 +297,10 @@ namespace Tesses::CrossLang {
{
instrs.push_back(std::make_shared<SimpleChunkInstruction>(LINEINFO));
}
else if(name == "embeddir")
{
instrs.push_back(std::make_shared<SimpleChunkInstruction>(PUSHRESOUURCEDIR));
}
else if(name == "pushclosure")
{
auto closure = std::make_shared<ClosureChunkInstruction>(true);
@@ -325,6 +341,14 @@ namespace Tesses::CrossLang {
instrs.push_back(std::make_shared<PushResourceChunkInstruction>(str));
}
}
else if(name == "embedstrm")
{
if(i < tokens.size() && tokens[i].type == LexTokenType::String)
{
std::string str = tokens[i++].text;
instrs.push_back(std::make_shared<PushResourceStreamChunkInstruction>(str));
}
}
else if(name == "push")
{
if(IsSym("."))
@@ -1031,6 +1055,7 @@ namespace Tesses::CrossLang {
auto chr = std::dynamic_pointer_cast<PushCharChunkInstruction>(item);
auto chk = std::dynamic_pointer_cast<ClosureChunkInstruction>(item);
auto reso = std::dynamic_pointer_cast<PushResourceChunkInstruction>(item);
auto resos = std::dynamic_pointer_cast<PushResourceStreamChunkInstruction>(item);
auto jmp = std::dynamic_pointer_cast<JumpStyleChunkInstruction>(item);
auto scopeend = std::dynamic_pointer_cast<ScopeEndTimesChunkInstruction>(item);
if(lbl)
@@ -1066,6 +1091,10 @@ namespace Tesses::CrossLang {
{
chunks[chunkId].second.push_back(std::make_shared<EmbedInstruction>(GetResource(reso->value)));
}
if(resos)
{
chunks[chunkId].second.push_back(std::make_shared<EmbedStreamInstruction>(GetResource(reso->value)));
}
if(jmp)
{
chunks[chunkId].second.push_back(std::make_shared<JumpStyleInstruction>(jmp->instr,jmp->lbl));

View File

@@ -223,6 +223,7 @@ namespace Tesses::CrossLang {
{
switch(code[i++])
{
case PUSHRESOURCESTREAM:
case PUSHRESOURCE:
case PUSHSTRING:
case SCOPEENDTIMES:
@@ -381,6 +382,9 @@ namespace Tesses::CrossLang {
case APPENDDICT:
buffer.append("appenddict");
break;
case PUSHRESOUURCEDIR:
buffer.append("embeddir");
break;
case PUSHRESOURCE:
{
uint32_t clId = (uint32_t)code[i++] << 24;
@@ -391,6 +395,16 @@ namespace Tesses::CrossLang {
buffer.append(EscapeString(name + "-" + version.ToString()+"_"+ std::to_string(clId) + ".bin",true));
}
break;
case PUSHRESOURCESTREAM:
{
uint32_t clId = (uint32_t)code[i++] << 24;
clId |= (uint32_t)code[i++] << 16;
clId |= (uint32_t)code[i++] << 8;
clId |= (uint32_t)code[i++];
buffer.append("embedstrm ");
buffer.append(EscapeString(name + "-" + version.ToString()+"_"+ std::to_string(clId) + ".bin",true));
}
break;
case PUSHLONG:
{
uint64_t number = (uint64_t)code[i++] << 56;

View File

@@ -34,7 +34,7 @@ namespace Tesses::CrossLang
}
void CodeGen::Save(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, std::shared_ptr<Tesses::Framework::Streams::Stream> stream)
void CodeGen::Save(std::shared_ptr<Tesses::Framework::Streams::Stream> stream)
{
TVMVersion runtime_version(TVM_MAJOR,TVM_MINOR,TVM_PATCH,TVM_BUILD,TVM_VERSIONSTAGE);
uint8_t buffer[18];
@@ -235,7 +235,7 @@ namespace Tesses::CrossLang
{
memcpy(buffer,"RESO",4);
Write(stream,buffer,4);
WriteInt(stream,reso->GetLength(vfs));
WriteInt(stream,reso->GetLength(embedFS));
reso->Write(stream);
}
if(!this->icon.empty())
@@ -354,6 +354,21 @@ namespace Tesses::CrossLang
BitConverter::FromUint32BE(buff[0],this->n);
instr.insert(instr.end(),buff.begin(),buff.end());
}
EmbedStreamInstruction::EmbedStreamInstruction(uint32_t s)
{
this->n = s;
}
size_t EmbedStreamInstruction::Size()
{
return 5;
}
void EmbedStreamInstruction::Write(std::vector<uint8_t>& instr)
{
instr.push_back(PUSHRESOURCESTREAM);
std::array<uint8_t,4> buff;
BitConverter::FromUint32BE(buff[0],this->n);
instr.insert(instr.end(),buff.begin(),buff.end());
}
ClosureInstruction::ClosureInstruction(uint32_t s,bool hasScope)
{
this->n = s;
@@ -1365,6 +1380,49 @@ namespace Tesses::CrossLang
instructions.push_back(new EmbedInstruction(GetResource(std::make_shared<ResourceFile>(filename))));
}
else if(adv.nodeName == EmbedStreamExpression && adv.nodes.size() == 1 && std::holds_alternative<std::string>(adv.nodes[0]))
{
std::string filename = std::get<std::string>(adv.nodes[0]);
instructions.push_back(new EmbedStreamInstruction(GetResource(std::make_shared<ResourceFile>(filename))));
}
else if(adv.nodeName == EmbedDirectoryExpression && adv.nodes.size() == 1 && std::holds_alternative<std::string>(adv.nodes[0]))
{
std::string filename = std::get<std::string>(adv.nodes[0]);
std::function<void(Tesses::Framework::Filesystem::VFSPath path)> embedDir;
embedDir = [&](Tesses::Framework::Filesystem::VFSPath path)-> void {
instructions.push_back(new SimpleInstruction(CREATEDICTIONARY));
if(embedFS != nullptr && embedFS->DirectoryExists(path))
for(auto& item : embedFS->EnumeratePaths(path))
{
GenNode(instructions,item.GetFileName(),scope,contscope,brkscope,contI,brkI);
if(embedFS->DirectoryExists(item))
{
embedDir(item);
}
else if(embedFS->RegularFileExists(item))
{
auto ce = AdvancedSyntaxNode::Create(ClosureExpression,true,{
AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}),
AdvancedSyntaxNode::Create(ReturnStatement,false,{
AdvancedSyntaxNode::Create(EmbedStreamExpression,true,{item.ToString()})
})
});
GenNode(instructions,ce,scope,contscope,brkscope,contI,brkI);
}
else {
instructions.push_back(new SimpleInstruction(PUSHUNDEFINED));
}
instructions.push_back(new SimpleInstruction(APPENDDICT));
}
};
embedDir(filename);
//
//instructions.push_back(new EmbedStreamInstruction(GetResource(std::make_shared<ResourceFile>(filename))));
instructions.push_back(new SimpleInstruction(PUSHRESOUURCEDIR));
}
else if(adv.nodeName == HtmlRootExpression)
{
scope++;

View File

@@ -922,7 +922,7 @@ namespace Tesses::CrossLang
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
gen.Save(nullptr,ms);
gen.Save(ms);
ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
@@ -963,6 +963,26 @@ namespace Tesses::CrossLang
EnsureSymbol(")");
node = AdvancedSyntaxNode::Create(EmbedExpression, true,{embed.text});
}
else if(IsIdentifier("embedstrm"))
{
EnsureSymbol("(");
if(i >= tokens.size()) throw std::out_of_range("End of file");
auto embed = tokens[i];
i++;
if(embed.type != LexTokenType::String) throw SyntaxException(embed.lineInfo, "Expected an string for embed got a " + LexTokenType_ToString(embed.type) + " \"" + embed.text + "\"");
EnsureSymbol(")");
node = AdvancedSyntaxNode::Create(EmbedStreamExpression, true,{embed.text});
}
else if(IsIdentifier("embeddir"))
{
EnsureSymbol("(");
if(i >= tokens.size()) throw std::out_of_range("End of file");
auto embed = tokens[i];
i++;
if(embed.type != LexTokenType::String) throw SyntaxException(embed.lineInfo, "Expected an string for embed got a " + LexTokenType_ToString(embed.type) + " \"" + embed.text + "\"");
EnsureSymbol(")");
node = AdvancedSyntaxNode::Create(EmbedDirectoryExpression, true,{embed.text});
}
else if(tokens[i].type == LexTokenType::Identifier)
{
auto token=tokens[i];

View File

@@ -256,6 +256,10 @@ int main(int argc, char** argv)
Parser parser(tokens,gc,env);
parser.debug = debug;
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,LocalFS->SystemToVFSPath(resourceDir.string()));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
gen.name = name;
gen.version = version;
@@ -275,9 +279,7 @@ int main(int argc, char** argv)
{
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(outputDir / (name + "-" + version.ToString() + ".crvm"),"wb");
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,LocalFS->SystemToVFSPath(resourceDir.string()));
gen.Save(sfs,strm);
gen.Save(strm);
}
if(gc != nullptr)
{

View File

@@ -24,13 +24,14 @@ int main(int argc, char** argv)
Parser parser(tokens);
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
std::vector<uint8_t> data;
{
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
gen.Save(sfs,strm2);
gen.Save(strm2);
{
@@ -78,11 +79,12 @@ int main(int argc, char** argv)
Parser parser(tokens);
CodeGen gen;
gen.GenRoot(parser.ParseRoot());
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
gen.Save(sfs, strm2);
gen.Save(strm2);
}
else if(source == "exit")
@@ -98,11 +100,13 @@ int main(int argc, char** argv)
Parser parser(tokens);
CodeGen gen;
gen.GenRoot(parser.ParseRoot());
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
gen.embedFS = sfs;
gen.Save(sfs,strm2);
gen.GenRoot(parser.ParseRoot());
gen.Save(strm2);
}
{

View File

@@ -264,6 +264,7 @@ namespace Tesses::CrossLang
parser.debug = debug;
SyntaxNode n = parser.ParseRoot();
CodeGen gen;
gen.embedFS = vfs;
gen.GenRoot(n);
gen.dependencies = dependencies;
gen.tools = tools;
@@ -275,7 +276,7 @@ namespace Tesses::CrossLang
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
if(GetObject(_out, stream))
{
gen.Save(vfs, stream);
gen.Save(stream);
}

228
src/types/embed.cpp Normal file
View File

@@ -0,0 +1,228 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
EmbedStream::EmbedStream(GC* gc, TFile* file, uint32_t resource)
{
this->offset = 0;
this->resource = resource;
this->file = CreateMarkedTObject(gc,file);
}
bool EmbedStream::CanRead()
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return false;
if(this->offset >= file->resources[this->resource].size()) return false;
return true;
}
return false;
}
bool EmbedStream::CanSeek()
{
return true;
}
bool EmbedStream::EndOfStream()
{
return !CanRead();
}
size_t EmbedStream::Read(uint8_t* buff, size_t len)
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return 0;
auto flen = file->resources[this->resource].size();
if(this->offset >= flen) return 0;
len = std::min(len, std::min(
flen,
flen - this->offset
));
memcpy(buff,file->resources[this->resource].data() + this->offset,len);
this->offset += len;
return len;
}
return 0;
}
int64_t EmbedStream::GetPosition()
{
return (int64_t)this->offset;
}
int64_t EmbedStream::GetLength()
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return 0;
return (int64_t)file->resources[this->resource].size();
}
return 0;
}
void EmbedStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
{
switch(whence)
{
case Tesses::Framework::Streams::SeekOrigin::Begin:
this->offset = (uint32_t)pos;
break;
case Tesses::Framework::Streams::SeekOrigin::Current:
{
int64_t cur = this->offset;
cur += pos;
this->offset = (uint32_t)cur;
}
break;
case Tesses::Framework::Streams::SeekOrigin::End:
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return;
int64_t cur = (int64_t)file->resources[this->resource].size();
cur += pos;
this->offset = (uint32_t)cur;
}
break;
}
}
}
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path)
{
path = path.CollapseRelativeParents();
auto curEntry = this->dir->GetObject();
for(auto item : path.path)
{
TDictionary* dict;
if(GetObjectHeap(curEntry,dict) && dict->HasValue(item))
{
curEntry = dict->GetValue(item);
continue; //don't want to return undefined now do we
}
return Undefined();
}
return curEntry;
}
std::shared_ptr<Tesses::Framework::Streams::Stream> EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
{
if(mode != "r" && mode != "rb") return nullptr;
auto ent = getEntry(path);
TCallable* call;
if(GetObjectHeap(ent,call))
{
GCList ls(this->dir->GetGC());
auto fileO = call->Call(ls,{});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetObject(fileO,strm)) return strm;
}
return nullptr;
}
bool EmbedDirectory::RegularFileExists(Tesses::Framework::Filesystem::VFSPath path)
{
auto ent = getEntry(path);
TCallable* call;
return GetObjectHeap(ent,call);
}
bool EmbedDirectory::DirectoryExists(Tesses::Framework::Filesystem::VFSPath path)
{
auto ent = getEntry(path);
TDictionary* dict;
return GetObjectHeap(ent,dict);
}
class DICT_DIRENUM
{
GCList ls;
TDictionary* dict;
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
bool hasStarted = false;
public:
std::string GetCurrent()
{
return this->current->first;
}
DICT_DIRENUM(GC* gc, TDictionary* dict) : ls(gc), dict(dict)
{
ls.Add(dict);
}
bool MoveNext()
{
if(!this->hasStarted)
{
this->hasStarted=true;
this->current = this->dict->items.begin();
return !this->dict->items.empty();
}
else
{
this->current++;
return this->current != this->dict->items.end();
}
}
};
Tesses::Framework::Filesystem::VFSPathEnumerator EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
{
auto ent = getEntry(path);
TDictionary* dict;
if(GetObjectHeap(ent,dict))
{
DICT_DIRENUM* dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
Tesses::Framework::Filesystem::VFSPathEnumerator er(
[dir2,path](Tesses::Framework::Filesystem::VFSPath& path2)->bool {
if(dir2->MoveNext())
{
path2 = path / dir2->GetCurrent();
return true;
}
return false;
},
[dir2]()->void {
delete dir2;
}
);
return er;
}
return Tesses::Framework::Filesystem::VFSPathEnumerator();
}
EmbedDirectory::EmbedDirectory(GC* gc, TDictionary* dict)
{
this->dir = CreateMarkedTObject(gc, dict);
}
void EmbedDirectory::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path)
{
//DO NOTHING
}
void EmbedDirectory::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path)
{
}
void EmbedDirectory::DeleteFile(Tesses::Framework::Filesystem::VFSPath path)
{
}
void EmbedDirectory::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
{
}
std::string EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
{
return path.ToString();
}
Tesses::Framework::Filesystem::VFSPath EmbedDirectory::SystemToVFSPath(std::string path)
{
return path;
}
}

View File

@@ -123,7 +123,7 @@ namespace Tesses::CrossLang {
CodeGen gen;
gen.GenRoot(n);
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
gen.Save(nullptr, ms);
gen.Save(ms);
ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
TFile* f = TFile::Create(ls);
f->Load(ls.GetGC(),ms);

View File

@@ -6971,7 +6971,35 @@ namespace Tesses::CrossLang {
}
return false;
}
bool InterperterThread::PushResourceStream(GC* gc)
{
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
if(!cse.empty())
{
auto stk = cse.back();
std::vector<uint8_t>& code = stk->callable->closure->code;
if(stk->ip + 4 <= code.size())
{
uint32_t n=BitConverter::ToUint32BE(code[stk->ip]);
if(n >= stk->callable->file->resources.size())
throw VMException("Can't read resource.");
stk->ip = stk->ip + 4;
gc->BarrierBegin();
GCList ls(gc);
// TByteArray* arr = TByteArray::Create(ls);
// arr->data = stk->callable->file->resources[n];
stk->Push(gc, std::make_shared<EmbedStream>(gc,stk->callable->file,n));
gc->BarrierEnd();
}
else
{
throw VMException("Can't read chunk.");
}
}
return false;
}
bool InterperterThread::PushResource(GC* gc)
{
@@ -7016,6 +7044,21 @@ namespace Tesses::CrossLang {
}
return false;
}
bool InterperterThread::PushResourceDirectory(GC* gc)
{
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
GCList ls(gc);
auto _res2 = cse.back()->Pop(ls);
TDictionary* dict;
if(GetObjectHeap(_res2, dict))
{
cse.back()->Push(gc, std::make_shared<EmbedDirectory>(gc,dict));
}
else {
cse.back()->Push(gc, Undefined());
}
return false;
}
bool InterperterThread::JumpIfDefined(GC* gc)
{

View File

@@ -64,9 +64,9 @@ static opcode opcodes[256]={
&InterperterThread::JumpIfContinue,
&InterperterThread::JumpIfDefined,
&InterperterThread::DeclareConstVariable,
&InterperterThread::LineInfo,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::LineInfo,
&InterperterThread::PushResourceStream,
&InterperterThread::PushResourceDirectory,
&InterperterThread::Illegal,
&InterperterThread::Illegal,
&InterperterThread::Illegal,