Fix docker
This commit is contained in:
@ -8,8 +8,22 @@ jobs:
|
|||||||
withLfs: true
|
withLfs: true
|
||||||
withSubmodules: false
|
withSubmodules: false
|
||||||
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||||
|
- !CommandStep
|
||||||
|
name: Execute build
|
||||||
|
runInContainer: true
|
||||||
|
image: onedev.site.tesses.net/tesses-framework/tesses-framework:latest
|
||||||
|
interpreter: !DefaultInterpreter
|
||||||
|
commands: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -S .. -B .
|
||||||
|
make -j12
|
||||||
|
make install DESTDIR=out
|
||||||
|
useTTY: true
|
||||||
|
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||||
- !BuildImageStep
|
- !BuildImageStep
|
||||||
name: Build Docker Image
|
name: Build Docker Image
|
||||||
|
dockerfile: Dockerfile.run
|
||||||
output: !RegistryOutput
|
output: !RegistryOutput
|
||||||
tags: onedev.site.tesses.net/crosslang/crosslang:latest
|
tags: onedev.site.tesses.net/crosslang/crosslang:latest
|
||||||
registryLogins:
|
registryLogins:
|
||||||
@ -20,14 +34,7 @@ jobs:
|
|||||||
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||||
triggers:
|
triggers:
|
||||||
- !BranchUpdateTrigger
|
- !BranchUpdateTrigger
|
||||||
projects: crosslang
|
|
||||||
- !DependencyFinishedTrigger
|
|
||||||
projects: tesses-framework
|
projects: tesses-framework
|
||||||
projectDependencies:
|
|
||||||
- projectPath: tesses-framework
|
|
||||||
buildProvider: !LastFinishedBuild
|
|
||||||
jobName: Build for x86_64
|
|
||||||
artifacts: -**
|
|
||||||
retryCondition: never
|
retryCondition: never
|
||||||
maxRetries: 3
|
maxRetries: 3
|
||||||
retryDelay: 30
|
retryDelay: 30
|
||||||
|
|||||||
2
Dockerfile.run
Normal file
2
Dockerfile.run
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FROM onedev.site.tesses.net/tesses-framework/tesses-framework:latest
|
||||||
|
COPY build/out /
|
||||||
@ -646,6 +646,7 @@ class Parser {
|
|||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//this is a dummy type with
|
||||||
class MethodInvoker {
|
class MethodInvoker {
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -800,6 +801,8 @@ class GC {
|
|||||||
virtual TObject Call(GCList& ls,std::vector<TObject> args)=0;
|
virtual TObject Call(GCList& ls,std::vector<TObject> args)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TEnvironment : public THeapObject {
|
class TEnvironment : public THeapObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -993,6 +996,17 @@ class GC {
|
|||||||
TObject GetCurrent(GCList& ls);
|
TObject GetCurrent(GCList& ls);
|
||||||
void Mark();
|
void Mark();
|
||||||
};
|
};
|
||||||
|
class TDynamicListEnumerator : public TEnumerator
|
||||||
|
{
|
||||||
|
int64_t index;
|
||||||
|
TDynamicList* ls;
|
||||||
|
public:
|
||||||
|
static TDynamicListEnumerator* Create(GCList& ls, TDynamicList* list);
|
||||||
|
static TDynamicListEnumerator* Create(GCList* ls, TDynamicList* list);
|
||||||
|
bool MoveNext(GC* ls);
|
||||||
|
TObject GetCurrent(GCList& ls);
|
||||||
|
void Mark();
|
||||||
|
};
|
||||||
class TVFSPathEnumerator : public TEnumerator
|
class TVFSPathEnumerator : public TEnumerator
|
||||||
{
|
{
|
||||||
Tesses::Framework::Filesystem::VFSPathEnumerator enumerator;
|
Tesses::Framework::Filesystem::VFSPathEnumerator enumerator;
|
||||||
@ -1126,7 +1140,46 @@ class GC {
|
|||||||
TObject Call(GCList& ls,std::vector<TObject> args);
|
TObject Call(GCList& ls,std::vector<TObject> args);
|
||||||
void Mark();
|
void Mark();
|
||||||
};
|
};
|
||||||
|
class TDynamicList : public THeapObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TCallable* cb;
|
||||||
|
static TDynamicList* Create(GCList& ls,TCallable* callable);
|
||||||
|
static TDynamicList* Create(GCList* ls,TCallable* callable);
|
||||||
|
|
||||||
|
void Mark();
|
||||||
|
|
||||||
|
int64_t Count(GCList& ls);
|
||||||
|
|
||||||
|
TObject GetAt(GCList& ls, int64_t index);
|
||||||
|
|
||||||
|
void SetAt(GCList& ls, int64_t index, TObject val);
|
||||||
|
|
||||||
|
~TDynamicList();
|
||||||
|
};
|
||||||
|
class TDynamicDictionary : public THeapObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TCallable* cb;
|
||||||
|
|
||||||
|
static TDynamicDictionary* Create(GCList& ls,TCallable* callable);
|
||||||
|
static TDynamicDictionary* Create(GCList* ls,TCallable* callable);
|
||||||
|
|
||||||
|
void Mark();
|
||||||
|
|
||||||
|
TObject GetField(GCList& ls, std::string key);
|
||||||
|
|
||||||
|
void SetField(GCList& ls, std::string key, TObject value);
|
||||||
|
|
||||||
|
TObject CallMethod(GCList& ls, std::string name, std::vector<TObject> args);
|
||||||
|
|
||||||
|
bool MethodExists(GCList& ls, std::string name);
|
||||||
|
|
||||||
|
TEnumerator* GetEnumerator(GCList& ls);
|
||||||
|
|
||||||
|
|
||||||
|
~TDynamicDictionary();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class CallStackEntry : public THeapObject
|
class CallStackEntry : public THeapObject
|
||||||
|
|||||||
@ -2,36 +2,112 @@
|
|||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang
|
||||||
{
|
{
|
||||||
|
|
||||||
TObject Dictionary_Items(GCList& ls, std::vector<TObject> args)
|
TObject Dictionary_Items(GCList& ls, std::vector<TObject> args)
|
||||||
{
|
{
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary* dict;
|
||||||
|
TDynamicDictionary* dynDict;
|
||||||
if(args.size() == 1 && std::holds_alternative<THeapObjectHolder>(args[0]))
|
if(GetArgumentHeap(args,0,dynDict))
|
||||||
{
|
|
||||||
auto item = dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(args[0]).obj);
|
|
||||||
if(item != nullptr)
|
|
||||||
{
|
{
|
||||||
TDictionary* enumerableItem = TDictionary::Create(ls);
|
TDictionary* enumerableItem = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
|
|
||||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[item](GCList& ls2, std::vector<TObject> args)->TObject {
|
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||||
return TDictionaryEnumerator::Create(ls2,item);
|
return dynDict->GetEnumerator(ls2);
|
||||||
});
|
});
|
||||||
fn->watch.push_back(item);
|
fn->watch.push_back(dynDict);
|
||||||
|
|
||||||
enumerableItem->SetValue("GetEnumerator", fn);
|
enumerableItem->SetValue("GetEnumerator", fn);
|
||||||
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return enumerableItem;
|
return enumerableItem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(GetArgumentHeap(args,0,dict))
|
||||||
|
{
|
||||||
|
TDictionary* enumerableItem = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
|
||||||
|
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||||
|
return TDictionaryEnumerator::Create(ls2,dict);
|
||||||
|
});
|
||||||
|
fn->watch.push_back(dict);
|
||||||
|
|
||||||
|
enumerableItem->SetValue("GetEnumerator", fn);
|
||||||
|
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
|
return enumerableItem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
TObject Dictionary_GetField(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
TDictionary* dict;
|
||||||
|
TDynamicDictionary* dynDict;
|
||||||
|
std::string key;
|
||||||
|
if(GetArgument(args,1,key))
|
||||||
|
{
|
||||||
|
if(GetArgumentHeap(args,0,dict))
|
||||||
|
{
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
auto res = dict->GetValue(key);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
else if(GetArgumentHeap(args,0,dynDict))
|
||||||
|
{
|
||||||
|
return dynDict->GetField(ls,key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
TObject Dictionary_SetField(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
TDictionary* dict;
|
||||||
|
TDynamicDictionary* dynDict;
|
||||||
|
std::string key;
|
||||||
|
if(args.size() == 3 && GetArgument(args,1,key))
|
||||||
|
{
|
||||||
|
if(GetArgumentHeap(args,0,dict))
|
||||||
|
{
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue(key,args[2]);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
}
|
||||||
|
else if(GetArgumentHeap(args,0,dynDict))
|
||||||
|
{
|
||||||
|
dynDict->SetField(ls,key,args[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TObject Dictionary_GetField(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
TDictionary* dict;
|
||||||
|
TDynamicDictionary* dynDict;
|
||||||
|
std::string key;
|
||||||
|
if(GetArgument(args,1,key))
|
||||||
|
{
|
||||||
|
if(GetArgumentHeap(args,0,dict))
|
||||||
|
{
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
auto res = dict->GetValue(key);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
else if(GetArgumentHeap(args,0,dynDict))
|
||||||
|
{
|
||||||
|
return dynDict->GetField(ls,key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
void TStd::RegisterDictionary(GC* gc,TRootEnvironment* env)
|
void TStd::RegisterDictionary(GC* gc,TRootEnvironment* env)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -43,6 +119,8 @@ namespace Tesses::CrossLang
|
|||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
|
|
||||||
dict->DeclareFunction(gc, "Items","Get Dictionary Item Enumerable, for the each(item : Dictionary.Items(myDict)){item.Key; item.Value;}",{"dictionary"},Dictionary_Items);
|
dict->DeclareFunction(gc, "Items","Get Dictionary Item Enumerable, for the each(item : Dictionary.Items(myDict)){item.Key; item.Value;}",{"dictionary"},Dictionary_Items);
|
||||||
|
dict->DeclareFunction(gc, "SetField","Set a field in dictionary",{"dict","key","value"},Dictionary_SetField);
|
||||||
|
dict->DeclareFunction(gc, "GetField","Get a field in dictionary",{"dict","key"},Dictionary_GetField);
|
||||||
|
|
||||||
env->DeclareVariable("Dictionary", dict);
|
env->DeclareVariable("Dictionary", dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
|
|||||||
@ -2,7 +2,69 @@
|
|||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang
|
||||||
{
|
{
|
||||||
TObject TypeOf(GCList& ls, std::vector<TObject> args)
|
static TObject TypeIsDefined(GCList& ls,std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
return (!std::holds_alternative<std::nullptr_t>(args[0]) && !std::holds_alternative<Undefined>(args[0]));
|
||||||
|
}
|
||||||
|
static TObject TypeIsHeap(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
return std::holds_alternative<THeapObjectHolder>(args[0]);
|
||||||
|
}
|
||||||
|
static TObject TypeIsNumber(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
return std::holds_alternative<int64_t>(args[0]) || std::holds_alternative<double>(args[0]);
|
||||||
|
}
|
||||||
|
static TObject TypeIsLong(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
return std::holds_alternative<int64_t>(args[0]);
|
||||||
|
}
|
||||||
|
static TObject TypeIsDouble(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
return std::holds_alternative<double>(args[0]);
|
||||||
|
}
|
||||||
|
static TObject TypeIsString(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
return std::holds_alternative<std::string>(args[0]);
|
||||||
|
}
|
||||||
|
static TObject TypeIsCallable(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
TCallable* call;
|
||||||
|
return GetArgumentHeap(args,0,call);
|
||||||
|
}
|
||||||
|
static TObject TypeIsDictionary(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
TDictionary* dict;
|
||||||
|
TDynamicDictionary* dynDict;
|
||||||
|
return GetArgumentHeap(args,0,dict) || GetArgumentHeap(args,0,dynDict);
|
||||||
|
}
|
||||||
|
static TObject TypeIsList(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
TList* list;
|
||||||
|
TDynamicList* dynList;
|
||||||
|
return GetArgumentHeap(args,0,list) || GetArgumentHeap(args,0, dynList);
|
||||||
|
}
|
||||||
|
static TObject TypeIsStream(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
TStreamHeapObject* strm;
|
||||||
|
return GetArgumentHeap(args,0,strm);
|
||||||
|
}
|
||||||
|
static TObject TypeIsVFS(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
if(args.empty()) return nullptr;
|
||||||
|
TVFSHeapObject* vfs;
|
||||||
|
return GetArgumentHeap(args,0,vfs);
|
||||||
|
}
|
||||||
|
static TObject TypeOf(GCList& ls, std::vector<TObject> args)
|
||||||
{
|
{
|
||||||
if(args.size() < 1) return "Undefined";
|
if(args.size() < 1) return "Undefined";
|
||||||
if(std::holds_alternative<Undefined>(args[0])) return "Undefined";
|
if(std::holds_alternative<Undefined>(args[0])) return "Undefined";
|
||||||
@ -18,7 +80,10 @@ namespace Tesses::CrossLang
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(args[0]).obj;
|
auto obj = std::get<THeapObjectHolder>(args[0]).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
|
|
||||||
auto list = dynamic_cast<TList*>(obj);
|
auto list = dynamic_cast<TList*>(obj);
|
||||||
|
auto dynList = dynamic_cast<TDynamicList*>(obj);
|
||||||
auto argWrapper = dynamic_cast<TArgWrapper*>(obj);
|
auto argWrapper = dynamic_cast<TArgWrapper*>(obj);
|
||||||
auto closure = dynamic_cast<TClosure*>(obj);
|
auto closure = dynamic_cast<TClosure*>(obj);
|
||||||
auto externalMethod = dynamic_cast<TExternalMethod*>(obj);
|
auto externalMethod = dynamic_cast<TExternalMethod*>(obj);
|
||||||
@ -26,6 +91,8 @@ namespace Tesses::CrossLang
|
|||||||
auto native = dynamic_cast<TNative*>(obj);
|
auto native = dynamic_cast<TNative*>(obj);
|
||||||
auto vfs = dynamic_cast<TVFSHeapObject*>(obj);
|
auto vfs = dynamic_cast<TVFSHeapObject*>(obj);
|
||||||
auto strm = dynamic_cast<TStreamHeapObject*>(obj);
|
auto strm = dynamic_cast<TStreamHeapObject*>(obj);
|
||||||
|
if(dynDict != nullptr) return "DynamicDictionary";
|
||||||
|
if(dynList != nullptr) return "DynamicList";
|
||||||
if(strm != nullptr)
|
if(strm != nullptr)
|
||||||
{
|
{
|
||||||
auto netStrm = dynamic_cast<Tesses::Framework::Streams::NetworkStream*>(strm->stream);
|
auto netStrm = dynamic_cast<Tesses::Framework::Streams::NetworkStream*>(strm->stream);
|
||||||
@ -141,41 +208,6 @@ namespace Tesses::CrossLang
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static TObject Throw(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(!args.empty())
|
|
||||||
{
|
|
||||||
VMByteCodeException bce(ls.GetGC(),args[0]);
|
|
||||||
throw bce;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
static TObject Try(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
TCallable* tryPart;
|
|
||||||
TCallable* catchPart;
|
|
||||||
if(GetArgumentHeap(args,0,tryPart) && GetArgumentHeap(args,1,catchPart))
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
tryPart->Call(ls,{});
|
|
||||||
}
|
|
||||||
catch(VMByteCodeException& ex)
|
|
||||||
{
|
|
||||||
catchPart->Call(ls,{ex.exception});
|
|
||||||
}
|
|
||||||
catch(std::exception& ex)
|
|
||||||
{
|
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
|
||||||
auto gc = ls.GetGC();
|
|
||||||
gc->BarrierBegin();
|
|
||||||
dict->SetValue("Type","NativeException");
|
|
||||||
dict->SetValue("Text",ex.what());
|
|
||||||
gc->BarrierEnd();
|
|
||||||
catchPart->Call(ls,{dict});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
EnvironmentPermissions::EnvironmentPermissions()
|
EnvironmentPermissions::EnvironmentPermissions()
|
||||||
{
|
{
|
||||||
this->canRegisterConsole=false;
|
this->canRegisterConsole=false;
|
||||||
@ -203,11 +235,22 @@ namespace Tesses::CrossLang
|
|||||||
|
|
||||||
env->permissions.canRegisterRoot=true;
|
env->permissions.canRegisterRoot=true;
|
||||||
env->DeclareFunction(gc, "ParseLong","Parse Long from String",{"arg","$base"},ParseLong);
|
env->DeclareFunction(gc, "ParseLong","Parse Long from String",{"arg","$base"},ParseLong);
|
||||||
|
|
||||||
env->DeclareFunction(gc, "ParseDouble","Parse Double from String",{"arg"},ParseDouble);
|
env->DeclareFunction(gc, "ParseDouble","Parse Double from String",{"arg"},ParseDouble);
|
||||||
env->DeclareFunction(gc, "TypeOf","Get type of object",{"object"},TypeOf);
|
env->DeclareFunction(gc, "TypeOf","Get type of object",{"object"},TypeOf);
|
||||||
env->DeclareFunction(gc, "Throw", "Throw an exception",{"object"},Throw);
|
env->DeclareFunction(gc, "TypeIsDefined","Get whether object is not null or undefined",{"object"},TypeIsDefined);
|
||||||
env->DeclareFunction(gc, "Try", "Handle exceptions",{"callbackToTry","callbackToCatch"},Try);
|
env->DeclareFunction(gc, "TypeIsHeap","Get whether object is susceptible to garbage collection",{"object"},TypeIsHeap);
|
||||||
|
env->DeclareFunction(gc, "TypeIsNumber","Get whether object is a number",{"object"},TypeIsNumber);
|
||||||
|
env->DeclareFunction(gc, "TypeIsLong","Get whether object is a long (not a double)",{"object"},TypeIsLong);
|
||||||
|
env->DeclareFunction(gc, "TypeIsDouble","Get whether object is a double (not a long)",{"object"},TypeIsDouble);
|
||||||
|
env->DeclareFunction(gc, "TypeIsString","Get whether object is a string",{"object"},TypeIsString);
|
||||||
|
env->DeclareFunction(gc, "TypeIsCallable","Get whether object is callable",{"object"},TypeIsCallable);
|
||||||
|
env->DeclareFunction(gc, "TypeIsDictionary","Get whether object is a dictionary or dynamic dictionary",{"object"},TypeIsDictionary);
|
||||||
|
env->DeclareFunction(gc, "TypeIsList","Get whether object is a list or dynamic list",{"object"},TypeIsList);
|
||||||
|
env->DeclareFunction(gc, "TypeIsStream","Get whether object is a stream",{"object"},TypeIsStream);
|
||||||
|
env->DeclareFunction(gc, "TypeIsVFS","Get whether object is a virtual filesystem",{"object"},TypeIsVFS);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
env->DeclareFunction(gc, "Thread","Create thread",{"callback"},[](GCList& ls, std::vector<TObject> args)-> TObject
|
env->DeclareFunction(gc, "Thread","Create thread",{"callback"},[](GCList& ls, std::vector<TObject> args)-> TObject
|
||||||
{
|
{
|
||||||
if(args.size() == 1 && std::holds_alternative<THeapObjectHolder>(args[0]))
|
if(args.size() == 1 && std::holds_alternative<THeapObjectHolder>(args[0]))
|
||||||
@ -221,7 +264,9 @@ namespace Tesses::CrossLang
|
|||||||
return Undefined();
|
return Undefined();
|
||||||
});
|
});
|
||||||
env->DeclareFunction(gc,"ByteArray","Create bytearray, with optional either size (to size it) or string argument (to fill byte array)",{"$data"},ByteArray);
|
env->DeclareFunction(gc,"ByteArray","Create bytearray, with optional either size (to size it) or string argument (to fill byte array)",{"$data"},ByteArray);
|
||||||
|
gc->BarrierBegin();
|
||||||
|
env->DeclareVariable("InvokeMethod",MethodInvoker());
|
||||||
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
void TStd::RegisterStd(GC* gc, TRootEnvironment* env)
|
void TStd::RegisterStd(GC* gc, TRootEnvironment* env)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,96 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
|
TDynamicDictionary* TDynamicDictionary::Create(GCList& ls,TCallable* callable)
|
||||||
|
{
|
||||||
|
|
||||||
|
TDynamicDictionary* dict=new TDynamicDictionary();
|
||||||
|
dict->cb = callable;
|
||||||
|
GC* _gc = ls.GetGC();
|
||||||
|
ls.Add(dict);
|
||||||
|
_gc->Watch(dict);
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
TDynamicDictionary* TDynamicDictionary::Create(GCList* ls,TCallable* callable)
|
||||||
|
{
|
||||||
|
TDynamicDictionary* dict=new TDynamicDictionary();
|
||||||
|
dict->cb = callable;
|
||||||
|
GC* _gc = ls->GetGC();
|
||||||
|
ls->Add(dict);
|
||||||
|
_gc->Watch(dict);
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDynamicDictionary::Mark()
|
||||||
|
{
|
||||||
|
if(this->marked) return;
|
||||||
|
this->marked=true;
|
||||||
|
this->cb->Mark();
|
||||||
|
}
|
||||||
|
|
||||||
|
TObject TDynamicDictionary::GetField(GCList& ls, std::string key)
|
||||||
|
{
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "GetField");
|
||||||
|
dict->SetValue("Key", key);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return cb->Call(ls,{dict});
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDynamicDictionary::SetField(GCList& ls, std::string key, TObject value)
|
||||||
|
{
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "SetField");
|
||||||
|
dict->SetValue("Key", key);
|
||||||
|
dict->SetValue("Value", value);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
cb->Call(ls,{dict});
|
||||||
|
}
|
||||||
|
|
||||||
|
TObject TDynamicDictionary::CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "CallMethod");
|
||||||
|
dict->SetValue("Name", name);
|
||||||
|
auto argVal = TList::Create(ls);
|
||||||
|
argVal->items = args;
|
||||||
|
dict->SetValue("Arguments", argVal);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return cb->Call(ls,{dict});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEnumerator* TDynamicDictionary::GetEnumerator(GCList& ls)
|
||||||
|
{
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "GetEnumerator");
|
||||||
|
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
|
return TEnumerator::CreateFromObject(ls,cb->Call(ls,{dict}));
|
||||||
|
}
|
||||||
|
bool TDynamicDictionary::MethodExists(GCList& ls,std::string name)
|
||||||
|
{
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "MethodExists");
|
||||||
|
dict->SetValue("Name", name);
|
||||||
|
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
|
auto res = cb->Call(ls,{dict});
|
||||||
|
bool r2;
|
||||||
|
if(GetObject(res,r2)) return r2;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDynamicDictionary::~TDynamicDictionary()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
TObject TDictionary::CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
|
TObject TDictionary::CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
|
||||||
{
|
{
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
|
|||||||
@ -56,6 +56,8 @@ namespace Tesses::CrossLang
|
|||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
TList* mls;
|
TList* mls;
|
||||||
|
TDynamicList* dynList;
|
||||||
|
TDynamicDictionary* dynDict;
|
||||||
TDictionary* dict;
|
TDictionary* dict;
|
||||||
TEnumerator* enumerator;
|
TEnumerator* enumerator;
|
||||||
if(GetObject(obj,str))
|
if(GetObject(obj,str))
|
||||||
@ -66,6 +68,10 @@ namespace Tesses::CrossLang
|
|||||||
{
|
{
|
||||||
return TListEnumerator::Create(ls,mls);
|
return TListEnumerator::Create(ls,mls);
|
||||||
}
|
}
|
||||||
|
else if(GetObjectHeap(obj,dynList))
|
||||||
|
{
|
||||||
|
return TDynamicListEnumerator::Create(ls,dynList);
|
||||||
|
}
|
||||||
else if(GetObjectHeap(obj,dict))
|
else if(GetObjectHeap(obj,dict))
|
||||||
{
|
{
|
||||||
auto res=dict->CallMethod(ls,"GetEnumerator",{});
|
auto res=dict->CallMethod(ls,"GetEnumerator",{});
|
||||||
@ -208,6 +214,52 @@ namespace Tesses::CrossLang
|
|||||||
this->ls->Mark();
|
this->ls->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList& ls, TDynamicList* list)
|
||||||
|
{
|
||||||
|
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
|
||||||
|
liste->ls = list;
|
||||||
|
liste->index = -1;
|
||||||
|
GC* _gc = ls.GetGC();
|
||||||
|
ls.Add(liste);
|
||||||
|
_gc->Watch(liste);
|
||||||
|
return liste;
|
||||||
|
}
|
||||||
|
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList* ls, TDynamicList* list)
|
||||||
|
{
|
||||||
|
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
|
||||||
|
liste->ls = list;
|
||||||
|
liste->index = -1;
|
||||||
|
GC* _gc = ls->GetGC();
|
||||||
|
ls->Add(liste);
|
||||||
|
_gc->Watch(liste);
|
||||||
|
return liste;
|
||||||
|
}
|
||||||
|
bool TDynamicListEnumerator::MoveNext(GC* ls)
|
||||||
|
{
|
||||||
|
this->index++;
|
||||||
|
GCList ls2(ls);
|
||||||
|
return this->index >= 0 && this->index < this->ls->Count(ls2);
|
||||||
|
}
|
||||||
|
TObject TDynamicListEnumerator::GetCurrent(GCList& ls)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->index < -1) return nullptr;
|
||||||
|
auto r = this->ls->Count(ls);
|
||||||
|
if(r == 0) return nullptr;
|
||||||
|
if(this->index >= r) return nullptr;
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
TObject o = this->ls->GetAt(ls,index);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
void TDynamicListEnumerator::Mark()
|
||||||
|
{
|
||||||
|
if(this->marked) return;
|
||||||
|
this->marked = true;
|
||||||
|
this->ls->Mark();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TStringEnumerator* TStringEnumerator::Create(GCList& ls,std::string str)
|
TStringEnumerator* TStringEnumerator::Create(GCList& ls,std::string str)
|
||||||
{
|
{
|
||||||
TStringEnumerator* stre=new TStringEnumerator();
|
TStringEnumerator* stre=new TStringEnumerator();
|
||||||
|
|||||||
@ -1,5 +1,72 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
|
TDynamicList* TDynamicList::Create(GCList& ls,TCallable* callable)
|
||||||
|
{
|
||||||
|
TDynamicList* list=new TDynamicList();
|
||||||
|
list->cb = callable;
|
||||||
|
GC* _gc = ls.GetGC();
|
||||||
|
ls.Add(list);
|
||||||
|
_gc->Watch(list);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
TDynamicList* TDynamicList::Create(GCList* ls,TCallable* callable)
|
||||||
|
{
|
||||||
|
TDynamicList* list=new TDynamicList();
|
||||||
|
list->cb = callable;
|
||||||
|
GC* _gc = ls->GetGC();
|
||||||
|
ls->Add(list);
|
||||||
|
_gc->Watch(list);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDynamicList::Mark()
|
||||||
|
{
|
||||||
|
if(this->marked) return;
|
||||||
|
this->marked=true;
|
||||||
|
this->cb->Mark();
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t TDynamicList::Count(GCList& ls)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "Count");
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
auto res = cb->Call(ls,{dict});
|
||||||
|
int64_t n;
|
||||||
|
if(GetObject(res,n)) return n;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TObject TDynamicList::GetAt(GCList& ls, int64_t index)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "GetAt");
|
||||||
|
dict->SetValue("Index",index);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return cb->Call(ls,{dict});
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDynamicList::SetAt(GCList& ls, int64_t index, TObject val)
|
||||||
|
{
|
||||||
|
auto dict = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
dict->SetValue("Type", "SetAt");
|
||||||
|
dict->SetValue("Index",index);
|
||||||
|
dict->SetValue("Value",val);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
cb->Call(ls,{dict});
|
||||||
|
}
|
||||||
|
|
||||||
|
TDynamicList::~TDynamicList()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TByteArray* TByteArray::Create(GCList& ls)
|
TByteArray* TByteArray::Create(GCList& ls)
|
||||||
{
|
{
|
||||||
TByteArray* arr=new TByteArray();
|
TByteArray* arr=new TByteArray();
|
||||||
|
|||||||
141
src/vm/vm.cpp
141
src/vm/vm.cpp
@ -191,6 +191,7 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -198,6 +199,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator-",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -238,6 +244,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -245,6 +253,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator*",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -306,6 +319,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -313,6 +328,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator/",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -354,6 +374,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -361,6 +383,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator%",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -393,6 +420,7 @@ namespace Tesses::CrossLang {
|
|||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -400,6 +428,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeOne(ls,negfn,left);
|
return InvokeOne(ls,negfn,left);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator-",{}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,nullptr);
|
cse.back()->Push(gc,nullptr);
|
||||||
@ -442,6 +475,7 @@ namespace Tesses::CrossLang {
|
|||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -449,6 +483,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeOne(ls,negfn,left);
|
return InvokeOne(ls,negfn,left);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator!",{}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc, !ToBool(left));
|
cse.back()->Push(gc, !ToBool(left));
|
||||||
@ -479,6 +518,7 @@ namespace Tesses::CrossLang {
|
|||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -486,6 +526,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeOne(ls,negfn,left);
|
return InvokeOne(ls,negfn,left);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator~",{}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -528,6 +573,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -535,6 +582,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator<",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -577,6 +629,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -584,6 +638,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator>",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -626,6 +685,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -633,6 +694,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator<=",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -675,6 +741,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -682,6 +750,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator>=",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -748,6 +821,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -758,6 +833,15 @@ namespace Tesses::CrossLang {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
auto res = dynDict->CallMethod(ls,"operator==",{right});
|
||||||
|
if(!std::holds_alternative<std::nullptr_t>(res) && std::holds_alternative<Undefined>(res))
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,res);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(std::holds_alternative<THeapObjectHolder>(right))
|
if(std::holds_alternative<THeapObjectHolder>(right))
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,obj == std::get<THeapObjectHolder>(right).obj);
|
cse.back()->Push(gc,obj == std::get<THeapObjectHolder>(right).obj);
|
||||||
@ -824,6 +908,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -833,6 +919,16 @@ namespace Tesses::CrossLang {
|
|||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto res = dynDict->CallMethod(ls,"operator!=",{right});
|
||||||
|
if(!std::holds_alternative<std::nullptr_t>(res) && std::holds_alternative<Undefined>(res))
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,res);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(std::holds_alternative<THeapObjectHolder>(right))
|
if(std::holds_alternative<THeapObjectHolder>(right))
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,obj != std::get<THeapObjectHolder>(right).obj);
|
cse.back()->Push(gc,obj != std::get<THeapObjectHolder>(right).obj);
|
||||||
@ -866,6 +962,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -873,6 +971,12 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator<<",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -901,6 +1005,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -908,6 +1014,12 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator>>",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -936,6 +1048,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -943,6 +1057,12 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator|",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -971,6 +1091,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -978,6 +1100,12 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator^",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -1006,6 +1134,8 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -1013,6 +1143,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator&",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc,Undefined());
|
cse.back()->Push(gc,Undefined());
|
||||||
@ -1130,6 +1265,7 @@ namespace Tesses::CrossLang {
|
|||||||
{
|
{
|
||||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||||
|
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
|
||||||
if(dict != nullptr)
|
if(dict != nullptr)
|
||||||
{
|
{
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
@ -1137,6 +1273,11 @@ namespace Tesses::CrossLang {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return InvokeTwo(ls,fn,left,right);
|
return InvokeTwo(ls,fn,left,right);
|
||||||
}
|
}
|
||||||
|
else if(dynDict != nullptr)
|
||||||
|
{
|
||||||
|
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator+",{right}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cse.back()->Push(gc, Undefined());
|
cse.back()->Push(gc, Undefined());
|
||||||
|
|||||||
Reference in New Issue
Block a user