Replace time-based GC with allocation-count trigger, migrate all Create factories to GCList::Create(), fix VFSPath root path, reorder TObject variant

This commit is contained in:
2026-09-01 05:15:43 -05:00
parent 56b74dc6fc
commit 2430b62232
38 changed files with 888 additions and 806 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ on:
- 'v*' - 'v*'
env: env:
TF_VERSION: 0.0.6 TF_VERSION: 0.0.7
PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }} PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }}
VERSION: ${{ gitea.ref_name }} VERSION: ${{ gitea.ref_name }}
RESULT_IMAGE_NAME: tesses50/crosslang RESULT_IMAGE_NAME: tesses50/crosslang
+3
View File
@@ -1,5 +1,8 @@
# Changelog # Changelog
## 0.0.10
Replace time-based GC with allocation-count trigger, migrate all Create factories to GCList::Create(), fix VFSPath root path, reorder TObject variant
## 0.0.9 ## 0.0.9
Fixed Process.ShellFileOrUrl was broken New.ShellFileOrUrl Fixed Process.ShellFileOrUrl was broken New.ShellFileOrUrl
+1 -1
View File
@@ -5,7 +5,7 @@ set(CROSSLANG_STATIC ${TESSESFRAMEWORK_STATIC} CACHE INTERNAL "For CrossLang" FO
FetchContent_Declare( FetchContent_Declare(
TessesFramework TessesFramework
GIT_REPOSITORY https://git.tesses.org/tesses50/tessesframework.git GIT_REPOSITORY https://git.tesses.org/tesses50/tessesframework.git
GIT_TAG bd0587779e68832cf382fe49b6b2e99474bcf81f GIT_TAG 5b54af1728907559999e446e56497055297a3696
) )
set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF) set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF)
FetchContent_MakeAvailable(TessesFramework) FetchContent_MakeAvailable(TessesFramework)
+1
View File
@@ -47,6 +47,7 @@ src/types/class.cpp
src/types/classenvironment.cpp src/types/classenvironment.cpp
src/types/random.cpp src/types/random.cpp
src/types/queryable.cpp src/types/queryable.cpp
src/types/exception.cpp
src/vm/filereader.cpp src/vm/filereader.cpp
src/vm/gc.cpp src/vm/gc.cpp
src/vm/gclist.cpp src/vm/gclist.cpp
+1 -1
View File
@@ -1,3 +1,3 @@
set(CROSSLANG_MAJOR_VERSION 0) set(CROSSLANG_MAJOR_VERSION 0)
set(CROSSLANG_MINOR_VERSION 0) set(CROSSLANG_MINOR_VERSION 0)
set(CROSSLANG_PATCH_VERSION 9) set(CROSSLANG_PATCH_VERSION 10)
+209 -69
View File
@@ -14,6 +14,7 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <time.h> #include <time.h>
#include <unordered_set>
#include <variant> #include <variant>
#include <vector> #include <vector>
@@ -35,6 +36,7 @@
* *
*/ */
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
constexpr uint32_t ALLOC_THRESHOLD = 10000;
using BitConverter = Tesses::Framework::Serialization::BitConverter; using BitConverter = Tesses::Framework::Serialization::BitConverter;
constexpr std::string_view VMName = "CrossLangVM"; constexpr std::string_view VMName = "CrossLangVM";
constexpr std::string_view VMHowToGet = "https://crosslang.tesseslanguage.com/"; constexpr std::string_view VMHowToGet = "https://crosslang.tesseslanguage.com/";
@@ -794,14 +796,16 @@ class ResourceByteArray : public ResourceBase {
GetLength(std::shared_ptr<Tesses::Framework::Filesystem::VFS> embedFS); GetLength(std::shared_ptr<Tesses::Framework::Filesystem::VFS> embedFS);
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> output); void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> output);
}; };
class CodeGen { class CodeGen {
uint32_t id; uint32_t id;
uint32_t NewId(); uint32_t NewId();
void GetFunctionArgs(std::vector<uint32_t> &args, SyntaxNode n); void GetFunctionArgs(std::vector<uint32_t> &args,
std::vector<ByteCodeInstruction *> &instructions,
SyntaxNode n);
void FlattenCommas(std::vector<uint32_t> &args, SyntaxNode n);
void GetFunctionName(std::vector<uint32_t> &name, SyntaxNode n); void GetFunctionName(std::vector<uint32_t> &name, SyntaxNode n);
void GetFunctionArgs(std::vector<SyntaxNode> &args, SyntaxNode n); void FlattenCommas(std::vector<SyntaxNode> &args, SyntaxNode n);
SyntaxNode StringifyListOfVars(SyntaxNode n); SyntaxNode StringifyListOfVars(SyntaxNode n);
uint32_t GetString(std::string str); uint32_t GetString(std::string str);
@@ -1347,8 +1351,10 @@ class THeapObject {
public: public:
bool marked; bool marked;
virtual void Mark() { marked = true; } virtual void Mark() { marked = true; }
THeapObject() = default;
virtual ~THeapObject() {} THeapObject(const THeapObject &) = delete;
THeapObject &operator=(const THeapObject &) = delete;
virtual ~THeapObject() = default;
}; };
class THeapObjectHolder { class THeapObjectHolder {
@@ -1369,9 +1375,9 @@ class TContinue {};
*/ */
using TObject = using TObject =
std::variant<int64_t, double, char, bool, std::string, std::regex, std::variant<Undefined, int64_t, double, char, bool, std::string,
Tesses::Framework::Filesystem::VFSPath, std::nullptr_t, std::regex, Tesses::Framework::Filesystem::VFSPath,
Undefined, MethodInvoker, THeapObjectHolder, TVMVersion, std::nullptr_t, MethodInvoker, THeapObjectHolder, TVMVersion,
std::shared_ptr<Tesses::Framework::Date::DateTime>, std::shared_ptr<Tesses::Framework::Date::DateTime>,
std::shared_ptr<Tesses::Framework::Date::TimeSpan>, TBreak, std::shared_ptr<Tesses::Framework::Date::TimeSpan>, TBreak,
TContinue, std::shared_ptr<Tesses::Framework::Streams::Stream>, TContinue, std::shared_ptr<Tesses::Framework::Streams::Stream>,
@@ -1387,50 +1393,72 @@ using TObject =
Tesses::Framework::Uuid>; Tesses::Framework::Uuid>;
class TRootEnvironment; class TRootEnvironment;
class GCList;
class GC : public std::enable_shared_from_this<GC> { class GC : public std::enable_shared_from_this<GC> {
Tesses::Framework::Threading::Thread *thrd; Tesses::Framework::Threading::Thread *thrd;
Tesses::Framework::Threading::Mutex *mtx; Tesses::Framework::Threading::Mutex mtx;
Tesses::Framework::Threading::Cond cond;
uint32_t allocs = 0;
volatile std::atomic<bool> running; volatile std::atomic<bool> running;
std::vector<THeapObject *> roots; std::unordered_set<GCList *> roots;
std::vector<THeapObject *> objects; std::unordered_set<THeapObject *> objects;
Tesses::Framework::Lazy<Tesses::Framework::Threading::ThreadPool *> *tpool; Tesses::Framework::Lazy<Tesses::Framework::Threading::ThreadPool *> *tpool;
std::vector< std::vector<
std::function<void(std::shared_ptr<GC> gc, TRootEnvironment *env)>> std::function<void(std::shared_ptr<GC> gc, TRootEnvironment *env)>>
register_everything; register_everything;
void SetRoot(GCList *obj);
void UnsetRoot(GCList *obj);
public: public:
Tesses::Framework::Threading::ThreadPool *GetPool(); Tesses::Framework::Threading::ThreadPool *GetPool();
bool UsingNullThreads(); bool UsingNullThreads();
GC(); GC();
GC(const GC &) = delete;
GC &operator=(const GC &) = delete;
void Start(); void Start();
bool IsRunning(); bool IsRunning();
void BarrierBegin(); void BarrierBegin();
void BarrierEnd(); void BarrierEnd();
void Collect(); void Collect(std::vector<THeapObject *> &to_delete);
void Watch(TObject obj); void Watch(TObject obj);
void Unwatch(TObject obj); void Unwatch(TObject obj);
void SetRoot(TObject obj);
void UnsetRoot(TObject obj);
static void Mark(TObject obj); static void Mark(TObject obj);
void RegisterEverythingCallback( void RegisterEverythingCallback(
std::function<void(std::shared_ptr<GC> gc, TRootEnvironment *env)> cb); std::function<void(std::shared_ptr<GC> gc, TRootEnvironment *env)> cb);
void RegisterEverything(TRootEnvironment *env); void RegisterEverything(TRootEnvironment *env);
~GC(); ~GC();
// uses thread_local or std::map
static void SetCurrentFunction(CallStackEntry *fn);
// uses thread local or std::map
static CallStackEntry *GetCurrentFunction();
friend class GCList;
}; };
std::string GetObjectTypeString(TObject obj); std::string GetObjectTypeString(TObject obj);
std::string ToString(std::shared_ptr<GC> gc, TObject obj); std::string ToString(std::shared_ptr<GC> gc, TObject obj);
class GCList : public THeapObject { class GCList {
std::vector<THeapObject *> items; std::vector<THeapObject *> items;
std::shared_ptr<GC> gc; std::shared_ptr<GC> gc;
public: public:
GCList(std::shared_ptr<GC> gc); GCList(std::shared_ptr<GC> gc);
std::shared_ptr<GC> GetGC(); GCList(const GCList &) = delete;
GCList &operator=(const GCList &) = delete;
std::shared_ptr<GC> GetGC() const;
template <typename T, typename... TArgs> T *Create(TArgs &&...args) {
T *obj = new T(std::forward<TArgs>(args)...);
Add(obj);
gc->Watch(obj);
return obj;
}
void Add(TObject v); void Add(TObject v);
void Remove(TObject v); void Remove(TObject v);
void Mark(); void Mark();
@@ -1443,7 +1471,9 @@ class TFile;
class TFileChunk : public THeapObject { class TFileChunk : public THeapObject {
public: public:
[[deprecated("Use GCList::Create<T>() instead")]]
static TFileChunk *Create(GCList *gc); static TFileChunk *Create(GCList *gc);
[[deprecated("Use GCList::Create<T>() instead")]]
static TFileChunk *Create(GCList &gc); static TFileChunk *Create(GCList &gc);
TFile *file; TFile *file;
std::vector<uint8_t> code; std::vector<uint8_t> code;
@@ -1455,7 +1485,9 @@ class TFileChunk : public THeapObject {
class TByteArray : public THeapObject { class TByteArray : public THeapObject {
public: public:
std::vector<uint8_t> data; std::vector<uint8_t> data;
[[deprecated("Use GCList::Create<T>() instead")]]
static TByteArray *Create(GCList *gc); static TByteArray *Create(GCList *gc);
[[deprecated("Use GCList::Create<T>() instead")]]
static TByteArray *Create(GCList &gc); static TByteArray *Create(GCList &gc);
}; };
enum class TClassModifier { Private, Protected, Public, Static }; enum class TClassModifier { Private, Protected, Public, Static };
@@ -1488,7 +1520,9 @@ class TClassObjectEntry {
class TDictionary; class TDictionary;
class TFile : public THeapObject { class TFile : public THeapObject {
public: public:
[[deprecated("Use GCList::Create<T>() instead")]]
static TFile *Create(GCList *gc); static TFile *Create(GCList *gc);
[[deprecated("Use GCList::Create<T>() instead")]]
static TFile *Create(GCList &gc); static TFile *Create(GCList &gc);
std::vector<TFileChunk *> chunks; std::vector<TFileChunk *> chunks;
@@ -1504,7 +1538,7 @@ class TFile : public THeapObject {
std::string name; std::string name;
TVMVersion version; TVMVersion version;
std::string info; std::string info;
int32_t icon; int32_t icon = -1;
void Load(std::shared_ptr<GC> gc, void Load(std::shared_ptr<GC> gc,
std::shared_ptr<Tesses::Framework::Streams::Stream> strm); std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
@@ -1528,7 +1562,9 @@ class TFile : public THeapObject {
class TAssociativeArray : public THeapObject { class TAssociativeArray : public THeapObject {
public: public:
std::vector<std::pair<TObject, TObject>> items; std::vector<std::pair<TObject, TObject>> items;
[[deprecated("Use GCList::Create<T>() instead")]]
static TAssociativeArray *Create(GCList &ls); static TAssociativeArray *Create(GCList &ls);
[[deprecated("Use GCList::Create<T>() instead")]]
static TAssociativeArray *Create(GCList *ls); static TAssociativeArray *Create(GCList *ls);
void Set(std::shared_ptr<GC> gc, TObject key, TObject value); void Set(std::shared_ptr<GC> gc, TObject key, TObject value);
TObject Get(std::shared_ptr<GC> gc, TObject key); TObject Get(std::shared_ptr<GC> gc, TObject key);
@@ -1542,29 +1578,33 @@ class TAssociativeArray : public THeapObject {
class TList : public THeapObject { class TList : public THeapObject {
public: public:
TList() = default;
template <typename Itterator>
TList(Itterator begin, Itterator end) : items(begin, end) {}
TList(std::initializer_list<TObject> il) : items(il) {}
TList(int64_t capacity) { items.reserve(capacity); }
std::vector<TObject> items; std::vector<TObject> items;
[[deprecated("Use GCList::Create<T>() instead")]]
static TList *Create(GCList *gc); static TList *Create(GCList *gc);
[[deprecated("Use GCList::Create<T>() instead")]]
static TList *Create(GCList &gc); static TList *Create(GCList &gc);
template <typename Itterator> template <typename Itterator>
[[deprecated("Use GCList::Create<T>() instead")]]
static TList *Create(GCList *gc, Itterator begin, Itterator end) { static TList *Create(GCList *gc, Itterator begin, Itterator end) {
auto list = Create(gc); return gc->Create<TList>(begin, end);
gc->GetGC()->BarrierBegin();
for (Itterator i = begin; i != end; ++i) {
TObject item = *i;
list->Add(item);
}
gc->GetGC()->BarrierEnd();
return list;
} }
template <typename Itterator> template <typename Itterator>
[[deprecated("Use GCList::Create<T>() instead")]]
static TList *Create(GCList &gc, Itterator begin, Itterator end) { static TList *Create(GCList &gc, Itterator begin, Itterator end) {
return Create(&gc, begin, end); return gc.Create<TList>(begin, end);
} }
[[deprecated("Use GCList::Create<T>() instead")]]
static TList *Create(GCList *gc, std::initializer_list<TObject> il) { static TList *Create(GCList *gc, std::initializer_list<TObject> il) {
return Create(gc, il.begin(), il.end()); return gc->Create<TList>(il);
} }
[[deprecated("Use GCList::Create<T>() instead")]]
static TList *Create(GCList &gc, std::initializer_list<TObject> il) { static TList *Create(GCList &gc, std::initializer_list<TObject> il) {
return Create(gc, il.begin(), il.end()); return gc.Create<TList>(il);
} }
virtual int64_t Count(); virtual int64_t Count();
virtual TObject Get(int64_t index); virtual TObject Get(int64_t index);
@@ -1578,30 +1618,37 @@ class TList : public THeapObject {
using TDItem = std::pair<std::string, TObject>; using TDItem = std::pair<std::string, TObject>;
class TDictionary : public THeapObject { class TDictionary : public THeapObject {
public: public:
TDictionary() = default;
template <typename Itterator> TDictionary(Itterator begin, Itterator end) {
for (Itterator i = begin; i != end; ++i) {
TDItem &item = *i;
SetValue(item.first, item.second);
}
}
TDictionary(std::initializer_list<TDItem> il) {
for (auto &item : il) {
SetValue(item.first, item.second);
}
}
std::map<std::string, TObject> items; std::map<std::string, TObject> items;
[[deprecated("Use GCList::Create<T>() instead")]]
static TDictionary *Create(GCList *gc); static TDictionary *Create(GCList *gc);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDictionary *Create(GCList &gc); static TDictionary *Create(GCList &gc);
template <typename Itterator> template <typename Itterator>
static TDictionary *Create(GCList *gc, Itterator begin, Itterator end) { static TDictionary *Create(GCList *gc, Itterator begin, Itterator end) {
auto dict = Create(gc); return gc->Create<TDictionary>(begin, end);
gc->GetGC()->BarrierBegin();
for (Itterator i = begin; i != end; ++i) {
TDItem item = *i;
dict->SetValue(item.first, item.second);
}
gc->GetGC()->BarrierEnd();
return dict;
} }
template <typename Itterator> template <typename Itterator>
static TDictionary *Create(GCList &gc, Itterator begin, Itterator end) { static TDictionary *Create(GCList &gc, Itterator begin, Itterator end) {
return Create(&gc, begin, end); return gc.Create<TDictionary>(begin, end);
} }
static TDictionary *Create(GCList *gc, std::initializer_list<TDItem> il) { static TDictionary *Create(GCList *gc, std::initializer_list<TDItem> il) {
return Create(gc, il.begin(), il.end()); return gc->Create<TDictionary>(il);
} }
static TDictionary *Create(GCList &gc, std::initializer_list<TDItem> il) { static TDictionary *Create(GCList &gc, std::initializer_list<TDItem> il) {
return Create(gc, il.begin(), il.end()); return gc.Create<TDictionary>(il);
} }
virtual bool HasValue(std::string key); virtual bool HasValue(std::string key);
@@ -1641,9 +1688,11 @@ class TCallable : public THeapObject {
void ThrowFatalError(std::exception &ex); void ThrowFatalError(std::exception &ex);
void ThrowConstError(std::string key); void ThrowConstError(std::string key);
enum class TEnvironmentDeclType { TEDT_VAR, TEDT_CONST };
class TEnvironment : public THeapObject { class TEnvironment : public THeapObject {
std::vector<std::string> consts; protected:
std::unordered_map<std::string, TEnvironmentDeclType> decls;
public: public:
std::vector<TCallable *> defers; std::vector<TCallable *> defers;
@@ -1700,8 +1749,10 @@ class TClassObject : public THeapObject {
std::vector<std::string> inherit_tree; std::vector<std::string> inherit_tree;
std::vector<TClassObjectEntry> entries; std::vector<TClassObjectEntry> entries;
// This is the only place where the old way is
static TClassObject *Create(GCList &ls, TFile *f, uint32_t classIndex, static TClassObject *Create(GCList &ls, TFile *f, uint32_t classIndex,
TEnvironment *env, std::vector<TObject> args); TEnvironment *env, std::vector<TObject> args);
// this too
static TClassObject *Create(GCList *ls, TFile *f, uint32_t classIndex, static TClassObject *Create(GCList *ls, TFile *f, uint32_t classIndex,
TEnvironment *env, std::vector<TObject> args); TEnvironment *env, std::vector<TObject> args);
@@ -1720,8 +1771,10 @@ class TClassEnvironment : public TEnvironment {
TClassObject *clsObj; TClassObject *clsObj;
public: public:
[[deprecated("Use GCList::Create<T>() instead")]]
static TClassEnvironment *Create(GCList *gc, TEnvironment *env, static TClassEnvironment *Create(GCList *gc, TEnvironment *env,
TClassObject *obj); TClassObject *obj);
[[deprecated("Use GCList::Create<T>() instead")]]
static TClassEnvironment *Create(GCList &gc, TEnvironment *env, static TClassEnvironment *Create(GCList &gc, TEnvironment *env,
TClassObject *obj); TClassObject *obj);
TClassEnvironment(TEnvironment *env, TClassObject *obj); TClassEnvironment(TEnvironment *env, TClassObject *obj);
@@ -1796,7 +1849,9 @@ class TRootEnvironment : public TEnvironment {
Tesses::Framework::Filesystem::VFSPath path); Tesses::Framework::Filesystem::VFSPath path);
TDictionary *GetDictionary(); TDictionary *GetDictionary();
[[deprecated("Use GCList::Create<T>() instead")]]
static TRootEnvironment *Create(GCList *gc, TDictionary *dict); static TRootEnvironment *Create(GCList *gc, TDictionary *dict);
[[deprecated("Use GCList::Create<T>() instead")]]
static TRootEnvironment *Create(GCList &gc, TDictionary *dict); static TRootEnvironment *Create(GCList &gc, TDictionary *dict);
TRootEnvironment(TDictionary *dict); TRootEnvironment(TDictionary *dict);
bool HasVariable(std::string key); bool HasVariable(std::string key);
@@ -1856,8 +1911,10 @@ class TSubEnvironment : public TEnvironment {
TDictionary *dict; TDictionary *dict;
public: public:
[[deprecated("Use GCList::Create<T>() instead")]]
static TSubEnvironment *Create(GCList *gc, TEnvironment *env, static TSubEnvironment *Create(GCList *gc, TEnvironment *env,
TDictionary *dict); TDictionary *dict);
[[deprecated("Use GCList::Create<T>() instead")]]
static TSubEnvironment *Create(GCList &gc, TEnvironment *env, static TSubEnvironment *Create(GCList &gc, TEnvironment *env,
TDictionary *dict); TDictionary *dict);
TSubEnvironment(TEnvironment *env, TDictionary *dict); TSubEnvironment(TEnvironment *env, TDictionary *dict);
@@ -1883,7 +1940,10 @@ TDictionary *CreateThread(GCList &ls, TCallable *callable, bool detached);
class TArgWrapper : public TCallable { class TArgWrapper : public TCallable {
public: public:
TCallable *callable; TCallable *callable;
TArgWrapper(TCallable *callable);
[[deprecated("Use GCList::Create<T>() instead")]]
static TArgWrapper *Create(GCList &ls, TCallable *callable); static TArgWrapper *Create(GCList &ls, TCallable *callable);
[[deprecated("Use GCList::Create<T>() instead")]]
static TArgWrapper *Create(GCList *ls, TCallable *callable); static TArgWrapper *Create(GCList *ls, TCallable *callable);
TObject Call(GCList &ls, std::vector<TObject> args); TObject Call(GCList &ls, std::vector<TObject> args);
void Mark(); void Mark();
@@ -1897,24 +1957,28 @@ class TExternalMethod : public TCallable {
std::vector<std::string> args; std::vector<std::string> args;
std::vector<TObject> watch; std::vector<TObject> watch;
TExternalMethod( TExternalMethod(
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::string documentation, std::vector<std::string> argNames, std::string documentation, std::vector<std::string> argNames,
std::function<void()> destroy); std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy = nullptr);
[[deprecated("Use GCList::Create<T>() instead")]]
static TExternalMethod * static TExternalMethod *
Create(GCList &ls, std::string documentation, Create(GCList &ls, std::string documentation,
std::vector<std::string> argNames, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb, std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy); std::function<void()> destroy);
[[deprecated("Use GCList::Create<T>() instead")]]
static TExternalMethod * static TExternalMethod *
Create(GCList *ls, std::string documentation, Create(GCList *ls, std::string documentation,
std::vector<std::string> argNames, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb, std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy); std::function<void()> destroy);
[[deprecated("Use GCList::Create<T>() instead")]]
static TExternalMethod * static TExternalMethod *
Create(GCList &ls, std::string documentation, Create(GCList &ls, std::string documentation,
std::vector<std::string> argNames, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb); std::function<TObject(GCList &ls, std::vector<TObject> args)> cb);
[[deprecated("Use GCList::Create<T>() instead")]]
static TExternalMethod * static TExternalMethod *
Create(GCList *ls, std::string documentation, Create(GCList *ls, std::string documentation,
std::vector<std::string> argNames, std::vector<std::string> argNames,
@@ -1943,8 +2007,11 @@ class TAssociativeArrayEnumerator : public TEnumerator {
TAssociativeArray *ls; TAssociativeArray *ls;
public: public:
TAssociativeArrayEnumerator(TAssociativeArray *list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TAssociativeArrayEnumerator *Create(GCList &ls, static TAssociativeArrayEnumerator *Create(GCList &ls,
TAssociativeArray *list); TAssociativeArray *list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TAssociativeArrayEnumerator *Create(GCList *ls, static TAssociativeArrayEnumerator *Create(GCList *ls,
TAssociativeArray *list); TAssociativeArray *list);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
@@ -1955,10 +2022,13 @@ class TAssociativeArrayEnumerator : public TEnumerator {
class TCustomEnumerator : public TEnumerator { class TCustomEnumerator : public TEnumerator {
public: public:
TDictionary *dict; TDictionary *dict;
TCustomEnumerator(TDictionary *dict);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
TObject GetCurrent(GCList &ls); TObject GetCurrent(GCList &ls);
void Mark(); void Mark();
[[deprecated("Use GCList::Create<T>() instead")]]
static TCustomEnumerator *Create(GCList &ls, TDictionary *dict); static TCustomEnumerator *Create(GCList &ls, TDictionary *dict);
[[deprecated("Use GCList::Create<T>() instead")]]
static TCustomEnumerator *Create(GCList *ls, TDictionary *dict); static TCustomEnumerator *Create(GCList *ls, TDictionary *dict);
}; };
@@ -1968,10 +2038,13 @@ class TYieldEnumerator : public TEnumerator {
TObject current; TObject current;
public: public:
TYieldEnumerator(TObject v);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
TObject GetCurrent(GCList &ls); TObject GetCurrent(GCList &ls);
void Mark(); void Mark();
[[deprecated("Use GCList::Create<T>() instead")]]
static TYieldEnumerator *Create(GCList &ls, TObject v); static TYieldEnumerator *Create(GCList &ls, TObject v);
[[deprecated("Use GCList::Create<T>() instead")]]
static TYieldEnumerator *Create(GCList *ls, TObject v); static TYieldEnumerator *Create(GCList *ls, TObject v);
}; };
@@ -1981,7 +2054,10 @@ class TStringEnumerator : public TEnumerator {
std::string str; std::string str;
public: public:
TStringEnumerator(std::string str);
[[deprecated("Use GCList::Create<T>() instead")]]
static TStringEnumerator *Create(GCList &ls, std::string str); static TStringEnumerator *Create(GCList &ls, std::string str);
[[deprecated("Use GCList::Create<T>() instead")]]
static TStringEnumerator *Create(GCList *ls, std::string str); static TStringEnumerator *Create(GCList *ls, std::string str);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
TObject GetCurrent(GCList &ls); TObject GetCurrent(GCList &ls);
@@ -1992,7 +2068,10 @@ class TListEnumerator : public TEnumerator {
TList *ls; TList *ls;
public: public:
TListEnumerator(TList *list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TListEnumerator *Create(GCList &ls, TList *list); static TListEnumerator *Create(GCList &ls, TList *list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TListEnumerator *Create(GCList *ls, TList *list); static TListEnumerator *Create(GCList *ls, TList *list);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
TObject GetCurrent(GCList &ls); TObject GetCurrent(GCList &ls);
@@ -2005,7 +2084,10 @@ class TDynamicListEnumerator : public TEnumerator {
TDynamicList *ls; TDynamicList *ls;
public: public:
TDynamicListEnumerator(TDynamicList *list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDynamicListEnumerator *Create(GCList &ls, TDynamicList *list); static TDynamicListEnumerator *Create(GCList &ls, TDynamicList *list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDynamicListEnumerator *Create(GCList *ls, TDynamicList *list); static TDynamicListEnumerator *Create(GCList *ls, TDynamicList *list);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
TObject GetCurrent(GCList &ls); TObject GetCurrent(GCList &ls);
@@ -2015,8 +2097,11 @@ class TVFSPathEnumerator : public TEnumerator {
Tesses::Framework::Filesystem::VFSPathEnumerator enumerator; Tesses::Framework::Filesystem::VFSPathEnumerator enumerator;
public: public:
TVFSPathEnumerator(Tesses::Framework::Filesystem::VFSPathEnumerator list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TVFSPathEnumerator * static TVFSPathEnumerator *
Create(GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator list); Create(GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator list);
[[deprecated("Use GCList::Create<T>() instead")]]
static TVFSPathEnumerator * static TVFSPathEnumerator *
Create(GCList *ls, Tesses::Framework::Filesystem::VFSPathEnumerator list); Create(GCList *ls, Tesses::Framework::Filesystem::VFSPathEnumerator list);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
@@ -2105,7 +2190,10 @@ class TDictionaryEnumerator : public TEnumerator {
TDictionary *dict; TDictionary *dict;
public: public:
TDictionaryEnumerator(TDictionary *dict);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDictionaryEnumerator *Create(GCList &ls, TDictionary *dict); static TDictionaryEnumerator *Create(GCList &ls, TDictionary *dict);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDictionaryEnumerator *Create(GCList *ls, TDictionary *dict); static TDictionaryEnumerator *Create(GCList *ls, TDictionary *dict);
bool MoveNext(std::shared_ptr<GC> ls); bool MoveNext(std::shared_ptr<GC> ls);
TObject GetCurrent(GCList &ls); TObject GetCurrent(GCList &ls);
@@ -2114,8 +2202,12 @@ class TDictionaryEnumerator : public TEnumerator {
class TClosure : public TCallable { class TClosure : public TCallable {
public: public:
TClosure(TEnvironment *env, TFile *file, uint32_t chunkId,
bool ownScope = true);
[[deprecated("Use GCList::Create<T>() instead")]]
static TClosure *Create(GCList &ls, TEnvironment *env, TFile *file, static TClosure *Create(GCList &ls, TEnvironment *env, TFile *file,
uint32_t chunkId, bool ownScope = true); uint32_t chunkId, bool ownScope = true);
[[deprecated("Use GCList::Create<T>() instead")]]
static TClosure *Create(GCList *ls, TEnvironment *env, TFile *file, static TClosure *Create(GCList *ls, TEnvironment *env, TFile *file,
uint32_t chunkId, bool ownScope = true); uint32_t chunkId, bool ownScope = true);
bool ownScope; bool ownScope;
@@ -2130,7 +2222,10 @@ class TClosure : public TCallable {
class TDynamicList : public THeapObject { class TDynamicList : public THeapObject {
public: public:
TCallable *cb; TCallable *cb;
TDynamicList(TCallable *callable);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDynamicList *Create(GCList &ls, TCallable *callable); static TDynamicList *Create(GCList &ls, TCallable *callable);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDynamicList *Create(GCList *ls, TCallable *callable); static TDynamicList *Create(GCList *ls, TCallable *callable);
void Mark(); void Mark();
@@ -2154,8 +2249,10 @@ class TDynamicList : public THeapObject {
class TDynamicDictionary : public THeapObject { class TDynamicDictionary : public THeapObject {
public: public:
TCallable *cb; TCallable *cb;
TDynamicDictionary(TCallable *callable);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDynamicDictionary *Create(GCList &ls, TCallable *callable); static TDynamicDictionary *Create(GCList &ls, TCallable *callable);
[[deprecated("Use GCList::Create<T>() instead")]]
static TDynamicDictionary *Create(GCList *ls, TCallable *callable); static TDynamicDictionary *Create(GCList *ls, TCallable *callable);
void Mark(); void Mark();
@@ -2176,17 +2273,19 @@ class InterperterThread;
class CallStackEntry : public THeapObject { class CallStackEntry : public THeapObject {
public: public:
[[deprecated("Use GCList::Create<T>() instead")]]
static CallStackEntry *Create(GCList *ls); static CallStackEntry *Create(GCList *ls);
[[deprecated("Use GCList::Create<T>() instead")]]
static CallStackEntry *Create(GCList &ls); static CallStackEntry *Create(GCList &ls);
InterperterThread *thread; InterperterThread *thread = nullptr;
std::vector<TObject> stack; std::vector<TObject> stack;
TEnvironment *env; TEnvironment *env = nullptr;
TClosure *callable; TClosure *callable = nullptr;
uint32_t ip; uint32_t ip;
uint32_t scopes; uint32_t scopes;
int64_t srcline; int64_t srcline = -1;
std::string srcfile; std::string srcfile = "";
bool mustReturn; bool mustReturn = false;
void Mark(); void Mark();
void Push(std::shared_ptr<GC> gc, TObject v); void Push(std::shared_ptr<GC> gc, TObject v);
@@ -2203,6 +2302,7 @@ class TTask : public THeapObject {
TTask(std::shared_ptr<GC> gc); TTask(std::shared_ptr<GC> gc);
public: public:
// this still is needed
static TTask *Create(GCList &ls); static TTask *Create(GCList &ls);
bool IsCompleted(); bool IsCompleted();
@@ -2223,7 +2323,6 @@ class TTask : public THeapObject {
static TTask *FromResult(GCList &ls, TObject v); static TTask *FromResult(GCList &ls, TObject v);
}; };
extern thread_local CallStackEntry *current_function;
class InterperterThread : public THeapObject { class InterperterThread : public THeapObject {
private: private:
@@ -2309,7 +2408,9 @@ class InterperterThread : public THeapObject {
bool PushPrivateExpression(std::shared_ptr<GC> gc); bool PushPrivateExpression(std::shared_ptr<GC> gc);
public: public:
[[deprecated("Use GCList::Create<T>() instead")]]
static InterperterThread *Create(GCList *ls); static InterperterThread *Create(GCList *ls);
[[deprecated("Use GCList::Create<T>() instead")]]
static InterperterThread *Create(GCList &ls); static InterperterThread *Create(GCList &ls);
std::vector<CallStackEntry *> call_stack_entries; std::vector<CallStackEntry *> call_stack_entries;
virtual void Execute(std::shared_ptr<GC> gc); virtual void Execute(std::shared_ptr<GC> gc);
@@ -2328,34 +2429,31 @@ class VMException : public std::exception {
error_message.append(ex); error_message.append(ex);
} }
const std::string &GetMessage() { return error_message; }
const char *what() const noexcept override { return error_message.c_str(); } const char *what() const noexcept override { return error_message.c_str(); }
}; };
class TAny : public THeapObject { class TAny : public THeapObject {
public: public:
std::any any; std::any any;
TObject other; TObject other;
[[deprecated("Use GCList::Create<T>() instead")]]
static TAny *Create(GCList &ls); static TAny *Create(GCList &ls);
[[deprecated("Use GCList::Create<T>() instead")]]
static TAny *Create(GCList *ls); static TAny *Create(GCList *ls);
void Mark(); void Mark();
}; };
class TNativeObject : public THeapObject { class TNativeObject : public THeapObject {
public: public:
template <typename T, typename... TArgs> template <typename T, typename... TArgs>
static T *Create(GCList &ls, TArgs... args) { [[deprecated("Use GCList::Create<T>() instead")]]
T *obj = new T(args...); static T *Create(GCList &ls, TArgs &&...args) {
std::shared_ptr<GC> gc = ls.GetGC(); return ls.Create<T>(std::forward<TArgs>(args)...);
ls.Add(obj);
gc->Watch(obj);
return obj;
} }
template <typename T, typename... TArgs> template <typename T, typename... TArgs>
static T *Create(GCList *ls, TArgs... args) { [[deprecated("Use GCList::Create<T>() instead")]]
T *obj = new T(args...); static T *Create(GCList *ls, TArgs &&...args) {
std::shared_ptr<GC> gc = ls->GetGC(); return ls->Create<T>(std::forward<TArgs>(args)...);
ls->Add(obj);
gc->Watch(obj);
return obj;
} }
virtual TObject CallMethod(GCList &ls, std::string name, virtual TObject CallMethod(GCList &ls, std::string name,
@@ -2363,7 +2461,6 @@ class TNativeObject : public THeapObject {
virtual std::string TypeName() = 0; virtual std::string TypeName() = 0;
virtual bool ToBool(); virtual bool ToBool();
virtual bool Equals(std::shared_ptr<GC> gc, TObject right); virtual bool Equals(std::shared_ptr<GC> gc, TObject right);
virtual ~TNativeObject();
}; };
class TRandom : public TNativeObject { class TRandom : public TNativeObject {
public: public:
@@ -2380,13 +2477,15 @@ class TNative : public THeapObject {
public: public:
TObject other; TObject other;
TNative(void *ptr, std::function<void(void *)> destroy); TNative(void *ptr, std::function<void(void *)> destroy = nullptr);
bool GetDestroyed(); bool GetDestroyed();
void *GetPointer(); void *GetPointer();
void Destroy(); void Destroy();
void Mark(); void Mark();
[[deprecated("Use GCList::Create<T>() instead")]]
static TNative *Create(GCList &ls, void *ptr, static TNative *Create(GCList &ls, void *ptr,
std::function<void(void *)> destroy); std::function<void(void *)> destroy);
[[deprecated("Use GCList::Create<T>() instead")]]
static TNative *Create(GCList *ls, void *ptr, static TNative *Create(GCList *ls, void *ptr,
std::function<void(void *)> destroy); std::function<void(void *)> destroy);
~TNative(); ~TNative();
@@ -2525,9 +2624,9 @@ typedef void (*PluginFunction)(std::shared_ptr<GC> gc, TRootEnvironment *env);
void LoadPlugin(std::shared_ptr<GC> gc, TRootEnvironment *env, void LoadPlugin(std::shared_ptr<GC> gc, TRootEnvironment *env,
Tesses::Framework::Filesystem::VFSPath sharedObjectPath); Tesses::Framework::Filesystem::VFSPath sharedObjectPath);
std::string Json_Encode(TObject o, bool indent = false); std::string Json_Encode(TObject o, bool indent = false);
TObject Json_Decode(GCList ls, std::string str); TObject Json_Decode(GCList &ls, std::string str);
std::string Json_DocEncode(TObject o, bool indent); std::string Json_DocEncode(TObject o, bool indent);
TObject Json_DocDecode(GCList ls, std::string str); TObject Json_DocDecode(GCList &ls, std::string str);
// DO NOT USE DIRECTLY // DO NOT USE DIRECTLY
class SharedPtrTObject { class SharedPtrTObject {
GCList *ls; GCList *ls;
@@ -2586,6 +2685,44 @@ class EmbedDirectory : public Tesses::Framework::Filesystem::VFS {
Tesses::Framework::Filesystem::StatData &data); Tesses::Framework::Filesystem::StatData &data);
}; };
class TNativeException : public TNativeObject {
std::string what;
std::exception_ptr ptr;
public:
TNativeException() = delete;
TNativeException(const char *what, std::exception_ptr ptr);
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args);
std::string TypeName();
std::string What();
std::exception_ptr GetPointer();
void ThrowIt();
};
class TException : public TNativeObject {
private:
TDictionary *extraFields;
TObject innerException;
std::string message;
std::string type;
std::optional<std::string> filename;
std::optional<uint32_t> line;
std::optional<uint32_t> column;
std::optional<uint32_t> offset;
public:
TException() = delete;
TException(std::string message, std::string type = "Exception",
TDictionary *extraFields = nullptr,
TObject innerException = Undefined());
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args);
std::string TypeName();
bool ToBool();
void Mark();
~TException() = default;
};
namespace Programs { namespace Programs {
int64_t CrossArchiveCreate(std::vector<std::string> &argv); int64_t CrossArchiveCreate(std::vector<std::string> &argv);
int64_t CrossArchiveExtract(std::vector<std::string> &argv); int64_t CrossArchiveExtract(std::vector<std::string> &argv);
@@ -2615,11 +2752,14 @@ class TQueryable : public THeapObject {
TObject parent; TObject parent;
TQueryableMode mode; TQueryableMode mode;
std::vector<TObject> args; std::vector<TObject> args;
public:
TQueryable(TObject parent); TQueryable(TObject parent);
TQueryable(TObject parent, TQueryableMode mode, std::vector<TObject> args); TQueryable(TObject parent, TQueryableMode mode, std::vector<TObject> args);
public: [[deprecated("Use GCList::Create<T>() instead")]]
static TQueryable *Create(GCList &ls, TObject parent); static TQueryable *Create(GCList &ls, TObject parent);
[[deprecated("Use GCList::Create<T>() instead")]]
static TQueryable *Create(GCList &ls, TObject parent, TQueryableMode mode, static TQueryable *Create(GCList &ls, TObject parent, TQueryableMode mode,
std::vector<TObject> args); std::vector<TObject> args);
+1 -1
View File
@@ -44,7 +44,7 @@ void CrossArchiveCreate(
strs.push_back("Console"); strs.push_back("Console");
strs.push_back("WriteLine"); strs.push_back("WriteLine");
strs.push_back("You are trying to run a crvm archive, stop it you won't " strs.push_back("You are trying to run a crvm archive, stop it you won't "
"get anywhere!\nUse crossarchiveextract instead."); "get anywhere!\nUse crosslang archiveextract instead.");
std::vector<std::string> resources; std::vector<std::string> resources;
+118 -34
View File
@@ -175,7 +175,7 @@ void CodeGen::WriteMetadataObject(std::vector<uint8_t> &bytes, SyntaxNode n) {
std::vector<SyntaxNode> itms; std::vector<SyntaxNode> itms;
if (asn.nodes.size() > 0) if (asn.nodes.size() > 0)
GetFunctionArgs(itms, asn.nodes[0]); FlattenCommas(itms, asn.nodes[0]);
bytes.push_back(7); bytes.push_back(7);
size_t offset = bytes.size(); size_t offset = bytes.size();
bytes.resize(offset + 4); bytes.resize(offset + 4);
@@ -189,7 +189,7 @@ void CodeGen::WriteMetadataObject(std::vector<uint8_t> &bytes, SyntaxNode n) {
std::vector<SyntaxNode> itms; std::vector<SyntaxNode> itms;
if (asn.nodes.size() > 0) if (asn.nodes.size() > 0)
GetFunctionArgs(itms, asn.nodes[0]); FlattenCommas(itms, asn.nodes[0]);
bytes.push_back(8); bytes.push_back(8);
size_t offset = bytes.size(); size_t offset = bytes.size();
bytes.resize(offset + 4); bytes.resize(offset + 4);
@@ -827,6 +827,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
size_t fnindex = this->chunks.size(); size_t fnindex = this->chunks.size();
ent.closure = (uint32_t)fnindex; ent.closure = (uint32_t)fnindex;
this->chunks.resize(fnindex + 1); this->chunks.resize(fnindex + 1);
std::vector<ByteCodeInstruction *> fnInstructions;
auto &nameAndArgs = auto &nameAndArgs =
std::get<AdvancedSyntaxNode>(adv2.nodes[2]); std::get<AdvancedSyntaxNode>(adv2.nodes[2]);
if (nameAndArgs.nodeName == FunctionCallExpression && if (nameAndArgs.nodeName == FunctionCallExpression &&
@@ -844,14 +846,13 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
std::get<std::string>(getvar.nodes[0])); std::get<std::string>(getvar.nodes[0]));
if (nameAndArgs.nodes.size() > 1) { if (nameAndArgs.nodes.size() > 1) {
GetFunctionArgs(ent.arguments, GetFunctionArgs(ent.arguments,
fnInstructions,
nameAndArgs.nodes[1]); nameAndArgs.nodes[1]);
} }
} else } else
continue; continue;
} }
std::vector<ByteCodeInstruction *> fnInstructions;
GenNode(fnInstructions, adv2.nodes[3], 0, -1, -1, -1, GenNode(fnInstructions, adv2.nodes[3], 0, -1, -1, -1,
-1); -1);
@@ -881,8 +882,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
ent.name = GetString( ent.name = GetString(
std::get<std::string>(getvar.nodes[0])); std::get<std::string>(getvar.nodes[0]));
if (nameAndArgs.nodes.size() > 1) { if (nameAndArgs.nodes.size() > 1) {
GetFunctionArgs(ent.arguments, FlattenCommas(ent.arguments,
nameAndArgs.nodes[1]); nameAndArgs.nodes[1]);
} }
} else } else
continue; continue;
@@ -1041,13 +1042,13 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
} }
if (item.first.second.nodeName == DefaultStatement) { if (item.first.second.nodeName == DefaultStatement) {
if (!defaultJmp.empty()) if (!defaultJmp.empty())
std::cout << "ERROR: multiple default in " Tesses::Framework::Console::WriteLine(
"switch statement will cause " "ERROR: multiple default in "
"undefined behaviour, this is not " "switch statement will cause "
"an exception due to not allowing " "undefined behaviour, this is not "
"exceptions in codegen stage (the " "an exception due to not allowing "
"compilation shouldn't fail)" "exceptions in codegen stage (the "
<< std::endl; "compilation shouldn't fail)");
defaultJmp = item.first.first; defaultJmp = item.first.first;
} }
} }
@@ -1223,7 +1224,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
std::vector<SyntaxNode> itms; std::vector<SyntaxNode> itms;
if (adv.nodes.size() > 0) if (adv.nodes.size() > 0)
GetFunctionArgs(itms, adv.nodes[0]); FlattenCommas(itms, adv.nodes[0]);
for (auto item : itms) { for (auto item : itms) {
GenNode(instructions, item, scope, contscope, brkscope, contI, GenNode(instructions, item, scope, contscope, brkscope, contI,
brkI); brkI);
@@ -1233,7 +1234,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
instructions.push_back(new SimpleInstruction(CREATEDICTIONARY)); instructions.push_back(new SimpleInstruction(CREATEDICTIONARY));
std::vector<SyntaxNode> itms; std::vector<SyntaxNode> itms;
if (adv.nodes.size() > 0) if (adv.nodes.size() > 0)
GetFunctionArgs(itms, adv.nodes[0]); FlattenCommas(itms, adv.nodes[0]);
for (auto item : itms) { for (auto item : itms) {
if (std::holds_alternative<AdvancedSyntaxNode>(item)) { if (std::holds_alternative<AdvancedSyntaxNode>(item)) {
auto tkn = std::get<AdvancedSyntaxNode>(item); auto tkn = std::get<AdvancedSyntaxNode>(item);
@@ -1273,7 +1274,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
contI, brkI); contI, brkI);
if (adv.nodes.size() == 2) { if (adv.nodes.size() == 2) {
std::vector<SyntaxNode> nodes; std::vector<SyntaxNode> nodes;
GetFunctionArgs(nodes, adv.nodes[1]); FlattenCommas(nodes, adv.nodes[1]);
for (auto item : nodes) for (auto item : nodes)
GenNode(instructions, item, scope, contscope, brkscope, GenNode(instructions, item, scope, contscope, brkscope,
contI, brkI); contI, brkI);
@@ -1288,7 +1289,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
contI, brkI); contI, brkI);
if (adv.nodes.size() == 2) { if (adv.nodes.size() == 2) {
std::vector<SyntaxNode> nodes; std::vector<SyntaxNode> nodes;
GetFunctionArgs(nodes, adv.nodes[1]); FlattenCommas(nodes, adv.nodes[1]);
for (auto item : nodes) for (auto item : nodes)
GenNode(instructions, item, scope, contscope, brkscope, GenNode(instructions, item, scope, contscope, brkscope,
contI, brkI); contI, brkI);
@@ -1555,7 +1556,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
} else if (adv.nodeName == ContinueStatement) { } else if (adv.nodeName == ContinueStatement) {
if (contscope == -1) { if (contscope == -1) {
std::cout << "WARN: continue does nothing here\n"; Tesses::Framework::Console::WriteLine(
"WARN: continue does nothing here");
} else if (contscope == -2) { } else if (contscope == -2) {
instructions.push_back(new SimpleInstruction(PUSHCONTINUE)); instructions.push_back(new SimpleInstruction(PUSHCONTINUE));
instructions.push_back(new SimpleInstruction(RET)); instructions.push_back(new SimpleInstruction(RET));
@@ -1572,7 +1574,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
} }
} else if (adv.nodeName == BreakStatement) { } else if (adv.nodeName == BreakStatement) {
if (brkscope == -1) { if (brkscope == -1) {
std::cout << "WARN: break does nothing here\n"; Tesses::Framework::Console::WriteLine(
"WARN: break does nothing here");
} else if (brkscope == -2) { } else if (brkscope == -2) {
instructions.push_back(new SimpleInstruction(PUSHBREAK)); instructions.push_back(new SimpleInstruction(PUSHBREAK));
instructions.push_back(new SimpleInstruction(RET)); instructions.push_back(new SimpleInstruction(RET));
@@ -1978,7 +1981,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
//(a,b) => {} //(a,b) => {}
// it has two args // it has two args
std::vector<uint32_t> args; std::vector<uint32_t> args;
GetFunctionArgs(args, adv.nodes[0]); FlattenCommas(args, adv.nodes[0]);
std::vector<ByteCodeInstruction *> fnInstructions; std::vector<ByteCodeInstruction *> fnInstructions;
size_t fnindex = this->chunks.size(); size_t fnindex = this->chunks.size();
@@ -2008,12 +2011,11 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
// Name => {} // Name => {}
//(a,b) => {} //(a,b) => {}
// it has two args // it has two args
std::vector<uint32_t> args;
GetFunctionArgs(args, adv.nodes[0]);
std::vector<ByteCodeInstruction *> fnInstructions; std::vector<ByteCodeInstruction *> fnInstructions;
size_t fnindex = this->chunks.size(); size_t fnindex = this->chunks.size();
this->chunks.resize(fnindex + 1); this->chunks.resize(fnindex + 1);
std::vector<uint32_t> args;
GetFunctionArgs(args, fnInstructions, adv.nodes[0]);
auto body = adv.nodes[1]; auto body = adv.nodes[1];
@@ -2060,18 +2062,20 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
} }
} }
} }
void CodeGen::GetFunctionArgs(std::vector<SyntaxNode> &args, SyntaxNode n) { void CodeGen::FlattenCommas(std::vector<SyntaxNode> &args, SyntaxNode n) {
AdvancedSyntaxNode sn; AdvancedSyntaxNode sn;
if (std::holds_alternative<AdvancedSyntaxNode>(n) && if (std::holds_alternative<AdvancedSyntaxNode>(n) &&
(sn = std::get<AdvancedSyntaxNode>(n)).nodeName == CommaExpression && (sn = std::get<AdvancedSyntaxNode>(n)).nodeName == CommaExpression &&
sn.nodes.size() == 2) { sn.nodes.size() == 2) {
GetFunctionArgs(args, sn.nodes[0]); FlattenCommas(args, sn.nodes[0]);
GetFunctionArgs(args, sn.nodes[1]); FlattenCommas(args, sn.nodes[1]);
} else { } else {
args.push_back(n); args.push_back(n);
} }
} }
void CodeGen::GetFunctionArgs(std::vector<uint32_t> &name, SyntaxNode n) { void CodeGen::GetFunctionArgs(std::vector<uint32_t> &name,
std::vector<ByteCodeInstruction *> &instrs,
SyntaxNode n) {
if (std::holds_alternative<std::nullptr_t>(n)) if (std::holds_alternative<std::nullptr_t>(n))
return; return;
@@ -2079,10 +2083,90 @@ void CodeGen::GetFunctionArgs(std::vector<uint32_t> &name, SyntaxNode n) {
auto res = std::get<AdvancedSyntaxNode>(n); auto res = std::get<AdvancedSyntaxNode>(n);
if (res.nodeName == ParenthesesExpression) { if (res.nodeName == ParenthesesExpression) {
for (auto n : res.nodes) for (auto n : res.nodes)
GetFunctionArgs(name, n); GetFunctionArgs(name, instrs, n);
} else if (res.nodeName == AssignExpression && res.nodes.size() == 2) {
// ennsure the left argument is a getVariableExpression
if (std::holds_alternative<AdvancedSyntaxNode>(res.nodes[0])) {
auto left = std::get<AdvancedSyntaxNode>(res.nodes[0]);
if (left.nodeName == GetVariableExpression &&
!left.nodes.empty() &&
std::holds_alternative<std::string>(left.nodes[0])) {
std::string key = std::get<std::string>(left.nodes[0]);
if (key.size() >= 2 && key[0] == '$' && key[1] == '$') {
Tesses::Framework::Console::WriteLine(
"WARN: you can't assign variadic functions to a "
"default value, this will be an "
"error on future release.");
return;
}
if (key.size() > 0 && key[0] == '$') {
key.erase(key.cbegin());
}
name.push_back(GetString('$' + key));
uint32_t ifId = NewId();
std::string compGenSetVar = "__compGenSetVar";
compGenSetVar.append(std::to_string(ifId));
std::string compGenSetVarEnd = "__compGenSetVarEnd";
compGenSetVarEnd.append(std::to_string(ifId));
GenNode(instrs,
AdvancedSyntaxNode::Create(GetVariableExpression,
true, {key}),
0, -1, -1, -1, -1);
instrs.push_back(new JumpStyleInstruction(
Tesses::CrossLang::Instruction::JMPUNDEFINED,
compGenSetVar));
instrs.push_back(new SimpleInstruction(POP));
instrs.push_back(new JumpStyleInstruction(
Tesses::CrossLang::Instruction::JMP, compGenSetVarEnd));
instrs.push_back(new LabelInstruction(compGenSetVar));
GenNode(instrs,
AdvancedSyntaxNode::Create(
AssignExpression, true,
{AdvancedSyntaxNode::Create(DeclareExpression,
true, {key}),
res.nodes[1]}),
0, -1, -1, -1, -1);
instrs.push_back(new SimpleInstruction(POP));
instrs.push_back(new LabelInstruction(compGenSetVarEnd));
} else {
Tesses::Framework::Console::WriteLine(
"WARN: assignment does not assign arg, this will be an "
"error on future release.");
}
} else {
Tesses::Framework::Console::WriteLine(
"WARN: assignment does not assign arg, this will be an "
"error on future release.");
}
} else if (res.nodeName == CommaExpression && res.nodes.size() == 2) { } else if (res.nodeName == CommaExpression && res.nodes.size() == 2) {
GetFunctionArgs(name, res.nodes[0]); GetFunctionArgs(name, instrs, res.nodes[0]);
GetFunctionArgs(name, res.nodes[1]); GetFunctionArgs(name, instrs, res.nodes[1]);
} else if (res.nodeName == GetVariableExpression &&
res.nodes.size() == 1) {
if (std::holds_alternative<std::string>(res.nodes[0])) {
name.push_back(GetString(std::get<std::string>(res.nodes[0])));
}
}
}
}
void CodeGen::FlattenCommas(std::vector<uint32_t> &name, SyntaxNode n) {
if (std::holds_alternative<std::nullptr_t>(n))
return;
if (std::holds_alternative<AdvancedSyntaxNode>(n)) {
auto res = std::get<AdvancedSyntaxNode>(n);
if (res.nodeName == ParenthesesExpression) {
for (auto n : res.nodes)
FlattenCommas(name, n);
} else if (res.nodeName == CommaExpression && res.nodes.size() == 2) {
FlattenCommas(name, res.nodes[0]);
FlattenCommas(name, res.nodes[1]);
} else if (res.nodeName == GetVariableExpression && } else if (res.nodeName == GetVariableExpression &&
res.nodes.size() == 1) { res.nodes.size() == 1) {
if (std::holds_alternative<std::string>(res.nodes[0])) { if (std::holds_alternative<std::string>(res.nodes[0])) {
@@ -2175,14 +2259,14 @@ void CodeGen::GenRoot(SyntaxNode n) {
functionName.insert( functionName.insert(
functionName.begin(), functionName.begin(),
{GetString(documentation)}); {GetString(documentation)});
if (fcalli.nodes.size() == 2)
GetFunctionArgs(args,
fcalli.nodes[1]);
std::vector<ByteCodeInstruction *> std::vector<ByteCodeInstruction *>
fnInstructions; fnInstructions;
size_t fnindex = this->chunks.size(); size_t fnindex = this->chunks.size();
this->chunks.resize(fnindex + 1); this->chunks.resize(fnindex + 1);
if (fcalli.nodes.size() == 2)
GetFunctionArgs(args,
fnInstructions,
fcalli.nodes[1]);
GenNode(fnInstructions, res2.nodes[1], GenNode(fnInstructions, res2.nodes[1],
0, -1, -1, -1, -1); 0, -1, -1, -1, -1);
+1 -1
View File
@@ -482,6 +482,7 @@ int Lex(std::string filename, std::istream &strm,
} }
break; break;
case '<': case '<':
case '>':
case '?': case '?':
if (peek == read) { if (peek == read) {
Flush(); Flush();
@@ -532,7 +533,6 @@ int Lex(std::string filename, std::istream &strm,
case '^': case '^':
case '~': case '~':
case '!': case '!':
case '>':
case '*': case '*':
case '%': case '%':
//* //*
+14 -153
View File
@@ -115,58 +115,16 @@ bool Parser::IsIdentifier(std::string txt, bool pop) {
} }
return false; return false;
} }
bool Parser::IsAnySymbol(std::initializer_list<std::string> idents, bool pop) { bool Parser::IsAnySymbol(std::initializer_list<std::string> idents, bool pop) {
if (i < tokens.size()) { if (i < tokens.size()) {
if (tokens[i].type != LexTokenType::Symbol) if (tokens[i].type != LexTokenType::Symbol)
return false; return false;
for (auto item : idents) { for (auto item : idents) {
if (item == ">") { if (item == tokens[i].text) {
if (i + 1 < tokens.size()) { tkn = tokens[i];
if ((tokens[i + 1].text == ">" || if (pop)
tokens[i + 1].text == ">=") && i++;
tokens[i + 1].type == LexTokenType::Symbol) return true;
continue;
}
if (item == tokens[i].text) {
tkn = tokens[i];
if (pop)
i++;
return true;
}
} else if (item == ">>=") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">=" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>=";
if (pop)
i += 2;
return true;
}
}
} else if (item == ">>") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>";
if (pop)
i += 2;
return true;
}
}
} else {
if (item == tokens[i].text) {
tkn = tokens[i];
if (pop)
i++;
return true;
}
} }
} }
} }
@@ -176,45 +134,7 @@ bool Parser::IsSymbol(std::string txt, bool pop) {
if (i < tokens.size()) { if (i < tokens.size()) {
if (tokens[i].type != LexTokenType::Symbol) if (tokens[i].type != LexTokenType::Symbol)
return false; return false;
if (txt == ">") { if (tokens[i].text == txt) {
if (i + 1 < tokens.size()) {
if ((tokens[i + 1].text == ">" || tokens[i + 1].text == ">=") &&
tokens[i + 1].type == LexTokenType::Symbol)
return false;
}
if (txt == tokens[i].text) {
tkn = tokens[i];
if (pop)
i++;
return true;
}
} else if (txt == ">>=") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">=" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>=";
if (pop)
i += 2;
return true;
}
}
} else if (txt == ">>") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>";
if (pop)
i += 2;
return true;
}
}
} else if (tokens[i].text == txt) {
tkn = tokens[i]; tkn = tokens[i];
if (pop) if (pop)
i++; i++;
@@ -233,7 +153,6 @@ static std::string EnsureSafeVariable(LexToken token) {
} }
void Parser::EnsureSymbol(std::string txt) { void Parser::EnsureSymbol(std::string txt) {
if (i < tokens.size()) { if (i < tokens.size()) {
if (tokens[i].type != LexTokenType::Symbol) { if (tokens[i].type != LexTokenType::Symbol) {
throw SyntaxException( throw SyntaxException(
tokens[i].lineInfo, tokens[i].lineInfo,
@@ -241,69 +160,7 @@ void Parser::EnsureSymbol(std::string txt) {
LexTokenType_ToString(tokens[i].type) + " \"" + LexTokenType_ToString(tokens[i].type) + " \"" +
tokens[i].text + "\" which is not a symbol at all."); tokens[i].text + "\" which is not a symbol at all.");
} }
if (txt == ">") { if (tokens[i].text != txt) {
if (i + 1 < tokens.size()) {
if ((tokens[i + 1].text == ">" || tokens[i + 1].text == ">=") &&
tokens[i + 1].type == LexTokenType::Symbol)
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text +
tokens[i + 1].text + "\"");
;
}
if (txt == tokens[i].text) {
tkn = tokens[i];
i++;
return;
}
}
if (txt == ">>=") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">=" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
i += 2;
return;
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + tokens[i + 1].text +
"\"");
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + "\"");
} else if (txt == ">>") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
i += 2;
return;
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + tokens[i + 1].text +
"\"");
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + "\"");
} else if (tokens[i].text != txt) {
throw SyntaxException(tokens[i].lineInfo, throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt + "expected the symbol \"" + txt +
@@ -633,6 +490,11 @@ void Parser::ParseHtml(std::vector<SyntaxNode> &nodes, std::string var) {
EnsureSymbol(")"); EnsureSymbol(")");
EnsureSymbol(">"); EnsureSymbol(">");
if (std::holds_alternative<std::nullptr_t>(item))
item = AdvancedSyntaxNode::Create(
DeclareExpression, true,
{"item"});
std::vector<SyntaxNode> _nodes; std::vector<SyntaxNode> _nodes;
parseFn(_nodes, "each"); parseFn(_nodes, "each");
body = AdvancedSyntaxNode::Create(ScopeNode, false, _nodes); body = AdvancedSyntaxNode::Create(ScopeNode, false, _nodes);
@@ -1411,7 +1273,7 @@ SyntaxNode Parser::ParseNode(bool isRoot) {
} }
if (!isRoot) if (!isRoot)
i++; EnsureSymbol("}");
return aSN; return aSN;
} }
@@ -1519,8 +1381,7 @@ SyntaxNode Parser::ParseNode(bool isRoot) {
if (std::holds_alternative<std::nullptr_t>(item)) if (std::holds_alternative<std::nullptr_t>(item))
item = AdvancedSyntaxNode::Create( item = AdvancedSyntaxNode::Create(
DeclareExpression, true, DeclareExpression, true,
{AdvancedSyntaxNode::Create(GetVariableExpression, true, {"item"});
{"item"})});
return AdvancedSyntaxNode::Create(EachStatement, false, return AdvancedSyntaxNode::Create(EachStatement, false,
{item, list, body}); {item, list, body});
+2 -2
View File
@@ -16,7 +16,7 @@ static void Help(std::string &filename) {
printf(" -n: Set name (MyAppOrLibName defaults to out)\n"); printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
printf(" -h, --help: Prints help\n"); printf(" -h, --help: Prints help\n");
printf("Options except for help have flag with arg like this: -F ARG\n"); printf("Options except for help have flag with arg like this: -F ARG\n");
exit(1); std::exit(1);
} }
int64_t CrossArchiveCreate(std::vector<std::string> &argv) { int64_t CrossArchiveCreate(std::vector<std::string> &argv) {
@@ -53,7 +53,7 @@ int64_t CrossArchiveCreate(std::vector<std::string> &argv) {
printf("Expected " printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]" "MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
"]]]\n"); "]]]\n");
exit(1); std::exit(1);
} }
} }
} else { } else {
+6 -6
View File
@@ -27,7 +27,7 @@ static void Help(std::string filename) {
"for sane with file access to current directory and sub " "for sane with file access to current directory and sub "
"directories, \"full\" has full runtime.\n"); "directories, \"full\" has full runtime.\n");
printf("Options except for help have flag with arg like this: -F ARG\n"); printf("Options except for help have flag with arg like this: -F ARG\n");
exit(1); std::exit(1);
} }
void CrossLangCompiler(std::vector<std::string> &argv) { void CrossLangCompiler(std::vector<std::string> &argv) {
/*std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary); /*std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
@@ -107,14 +107,14 @@ void CrossLangCompiler(std::vector<std::string> &argv) {
printf("Expected " printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-" "MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
"prod]]]]\n"); "prod]]]]\n");
exit(1); std::exit(1);
} }
dependencies.push_back( dependencies.push_back(
std::pair<std::string, TVMVersion>(str1, v2)); std::pair<std::string, TVMVersion>(str1, v2));
} else { } else {
printf("ERROR: Dependency must have version\n"); printf("ERROR: Dependency must have version\n");
exit(1); std::exit(1);
} }
} }
} else if (argv[i] == "-t") { } else if (argv[i] == "-t") {
@@ -137,14 +137,14 @@ void CrossLangCompiler(std::vector<std::string> &argv) {
printf("Expected " printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-" "MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
"prod]]]]\n"); "prod]]]]\n");
exit(1); std::exit(1);
} }
tools.push_back( tools.push_back(
std::pair<std::string, TVMVersion>(str1, v2)); std::pair<std::string, TVMVersion>(str1, v2));
} else { } else {
printf("ERROR: Tool must have version\n"); printf("ERROR: Tool must have version\n");
exit(1); std::exit(1);
} }
} }
} else if (argv[i] == "-n") { } else if (argv[i] == "-n") {
@@ -161,7 +161,7 @@ void CrossLangCompiler(std::vector<std::string> &argv) {
printf("Expected " printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]" "MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
"]]]\n"); "]]]\n");
exit(1); std::exit(1);
} }
} }
} else if (argv[i] == "-D" || argv[i] == "--debug") { } else if (argv[i] == "-D" || argv[i] == "--debug") {
+2 -2
View File
@@ -72,11 +72,11 @@ TObject Console_Write(GCList &ls, std::vector<TObject> args) {
TObject Console_Fatal(GCList &ls, std::vector<TObject> args) { TObject Console_Fatal(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) { if (args.size() < 1) {
Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>"); Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>");
exit(1); std::exit(1);
} }
Tesses::Framework::Console::ErrorLine("FATAL: " + Tesses::Framework::Console::ErrorLine("FATAL: " +
ToString(ls.GetGC(), args[0])); ToString(ls.GetGC(), args[0]));
exit(1); std::exit(1);
} }
TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) { TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) {
+2 -2
View File
@@ -159,7 +159,7 @@ static TObject JsonDocDecode(GCList &ls2, std::vector<TObject> args) {
std::string Json_Encode(TObject o, bool indent) { std::string Json_Encode(TObject o, bool indent) {
return Json::Encode(JsonSerialize(o), indent); return Json::Encode(JsonSerialize(o), indent);
} }
TObject Json_Decode(GCList ls, std::string str) { TObject Json_Decode(GCList &ls, std::string str) {
return JsonDeserialize(ls, Json::Decode(str)); return JsonDeserialize(ls, Json::Decode(str));
} }
std::string Json_DocEncode(TObject o, bool indent) { std::string Json_DocEncode(TObject o, bool indent) {
@@ -169,7 +169,7 @@ std::string Json_DocEncode(TObject o, bool indent) {
return Json::DocEncode(ls, indent); return Json::DocEncode(ls, indent);
return ""; return "";
} }
TObject Json_DocDecode(GCList ls, std::string str) { TObject Json_DocDecode(GCList &ls, std::string str) {
return JsonDeserialize(ls, Json::DocDecode(str)); return JsonDeserialize(ls, Json::DocDecode(str));
} }
void TStd::RegisterJson(std::shared_ptr<GC> gc, TRootEnvironment *env) { void TStd::RegisterJson(std::shared_ptr<GC> gc, TRootEnvironment *env) {
+59 -18
View File
@@ -150,6 +150,46 @@ class THttpDictionary : public TNativeObject {
value); value);
} }
return nullptr; return nullptr;
} else if (key == "TryGetOnlyOne") {
std::string key;
std::string value;
if (GetArgument(args, 0, key) && dict->TryGetOnlyOne(key, value)) {
return value;
}
return nullptr;
} else if (key == "TryGetOnlyOneBoolean") {
std::string key;
bool value;
if (GetArgument(args, 0, key) &&
dict->TryGetOnlyOneBoolean(key, value)) {
return value;
}
return nullptr;
} else if (key == "TryGetOnlyOneDouble") {
std::string key;
double value;
if (GetArgument(args, 0, key) &&
dict->TryGetOnlyOneDouble(key, value)) {
return value;
}
return nullptr;
} else if (key == "TryGetOnlyOneInt") {
std::string key;
int64_t value;
if (GetArgument(args, 0, key) &&
dict->TryGetOnlyOneInt(key, value)) {
return value;
}
return nullptr;
} else if (key == "TryGetOnlyOneDate") {
std::string key;
Tesses::Framework::Date::DateTime value;
if (GetArgument(args, 0, key) &&
dict->TryGetOnlyOneDate(key, value)) {
return std::make_shared<Tesses::Framework::Date::DateTime>(
value);
}
return nullptr;
} else if (key == "ToList") { } else if (key == "ToList") {
TList *_ls = TList::Create(ls); TList *_ls = TList::Create(ls);
for (auto item : dict->kvp) { for (auto item : dict->kvp) {
@@ -239,6 +279,9 @@ class TServerContext : public TNativeObjectThatReturnsHttpDictionary {
else if (key == "getQueryParams") else if (key == "getQueryParams")
return TNativeObject::Create<THttpDictionary>(ls, &ctx->queryParams, return TNativeObject::Create<THttpDictionary>(ls, &ctx->queryParams,
this); this);
else if (key == "getBodyParams")
return TNativeObject::Create<THttpDictionary>(ls, &ctx->bodyParams,
this);
else if (key == "getRequestHeaders") else if (key == "getRequestHeaders")
return TNativeObject::Create<THttpDictionary>( return TNativeObject::Create<THttpDictionary>(
ls, &ctx->requestHeaders, this); ls, &ctx->requestHeaders, this);
@@ -781,17 +824,19 @@ static TObject Net_Http_MimeType(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath p; Tesses::Framework::Filesystem::VFSPath p;
if (GetArgumentAsPath(args, 0, p)) { if (GetArgumentAsPath(args, 0, p)) {
std::filesystem::path p2 = p.GetFileName(); std::filesystem::path p2 = p.GetFileName();
return HttpUtils::MimeType(p2); return HttpUtils::GetMimeType(p2);
} }
return std::string("application/octet-stream"); return std::string("application/octet-stream");
} }
class THttpRequestBody : public TNativeObject { class THttpRequestBody : public TNativeObject {
HttpRequestBody *body; std::shared_ptr<HttpRequestBody> body;
public: public:
THttpRequestBody(HttpRequestBody *body) { this->body = body; } THttpRequestBody(std::shared_ptr<HttpRequestBody> body) {
this->body = body;
}
bool IsClosed() { return body == nullptr; } bool IsClosed() { return body == nullptr; }
HttpRequestBody *GetBody() { return this->body; } std::shared_ptr<HttpRequestBody> GetBody() { return this->body; }
std::string TypeName() { return "Net.Http.HttpRequestBody"; } std::string TypeName() { return "Net.Http.HttpRequestBody"; }
@@ -799,10 +844,7 @@ class THttpRequestBody : public TNativeObject {
return Undefined(); return Undefined();
} }
void Close() { void Close() { this->body = nullptr; }
delete this->body;
this->body = nullptr;
}
}; };
class THttpResponse : public TNativeObjectThatReturnsHttpDictionary { class THttpResponse : public TNativeObjectThatReturnsHttpDictionary {
@@ -907,7 +949,8 @@ static TObject Net_Http_MakeRequest(GCList &ls, std::vector<TObject> args,
_obj = options->GetValue("Body"); _obj = options->GetValue("Body");
if (GetObjectHeap(_obj, body1)) { if (GetObjectHeap(_obj, body1)) {
req.body = new TDictionaryHttpRequestBody(gc, body1); req.body =
std::make_shared<TDictionaryHttpRequestBody>(gc, body1);
} else if (GetObjectHeap(_obj, body2) && !body2->IsClosed()) { } else if (GetObjectHeap(_obj, body2) && !body2->IsClosed()) {
req.body = body2->GetBody(); req.body = body2->GetBody();
} }
@@ -920,8 +963,6 @@ static TObject Net_Http_MakeRequest(GCList &ls, std::vector<TObject> args,
if (req.body != nullptr) { if (req.body != nullptr) {
if (body2 != nullptr) { if (body2 != nullptr) {
body2->Close(); body2->Close();
} else if (body1 != nullptr) {
delete req.body;
} }
} }
@@ -1073,7 +1114,7 @@ static TObject Net_Http_WebSocketClient(GCList &ls, std::vector<TObject> args) {
if (GetArgument(args, 0, url) && GetArgumentHeap(args, 1, headers) && if (GetArgument(args, 0, url) && GetArgumentHeap(args, 1, headers) &&
GetArgumentHeap(args, 2, dict)) { GetArgumentHeap(args, 2, dict)) {
GetArgumentHeap(args, 3, callable); GetArgumentHeap(args, 3, callable);
HttpDictionary hdict; HttpDictionary hdict(false);
for (int64_t index = 0; index < headers->Count(); index++) { for (int64_t index = 0; index < headers->Count(); index++) {
_obj = headers->Get(index); _obj = headers->Get(index);
TDictionary *dict; TDictionary *dict;
@@ -1171,7 +1212,7 @@ static TObject Net_Http_WebSocketClient(GCList &ls, std::vector<TObject> args) {
if (!GetObjectHeap(hobj, headers)) if (!GetObjectHeap(hobj, headers))
return Undefined(); return Undefined();
HttpDictionary hdict; HttpDictionary hdict(false);
for (int64_t index = 0; index < headers->Count(); index++) { for (int64_t index = 0; index < headers->Count(); index++) {
_obj = headers->Get(index); _obj = headers->Get(index);
TDictionary *dict; TDictionary *dict;
@@ -1381,7 +1422,7 @@ static TObject New_StreamHttpRequestBody(GCList &ls,
if (GetArgument(args, 0, strm) && GetArgument(args, 1, mimeType)) { if (GetArgument(args, 0, strm) && GetArgument(args, 1, mimeType)) {
return TNativeObject::Create<THttpRequestBody>( return TNativeObject::Create<THttpRequestBody>(
ls, new StreamHttpRequestBody(strm, mimeType)); ls, std::make_shared<StreamHttpRequestBody>(strm, mimeType));
} }
return nullptr; return nullptr;
} }
@@ -1390,7 +1431,7 @@ static TObject New_TextHttpRequestBody(GCList &ls, std::vector<TObject> args) {
std::string mimeType; std::string mimeType;
if (GetArgument(args, 0, text) && GetArgument(args, 1, mimeType)) { if (GetArgument(args, 0, text) && GetArgument(args, 1, mimeType)) {
return TNativeObject::Create<THttpRequestBody>( return TNativeObject::Create<THttpRequestBody>(
ls, new TextHttpRequestBody(text, mimeType)); ls, std::make_shared<TextHttpRequestBody>(text, mimeType));
} }
return nullptr; return nullptr;
} }
@@ -1398,8 +1439,8 @@ static TObject New_JsonHttpRequestBody(GCList &ls, std::vector<TObject> args) {
if (!args.empty()) { if (!args.empty()) {
return TNativeObject::Create<THttpRequestBody>( return TNativeObject::Create<THttpRequestBody>(
ls, ls, std::make_shared<TextHttpRequestBody>(Json_Encode(args[0]),
new TextHttpRequestBody(Json_Encode(args[0]), "application/json")); "application/json"));
} }
return nullptr; return nullptr;
} }
@@ -1423,7 +1464,7 @@ void TStd::RegisterNet(std::shared_ptr<GC> gc, TRootEnvironment *env) {
"Create a text request body", {"text", "mimeType"}, "Create a text request body", {"text", "mimeType"},
New_TextHttpRequestBody); New_TextHttpRequestBody);
_new->DeclareFunction(gc, "JsonHttpRequestBody", _new->DeclareFunction(gc, "JsonHttpRequestBody",
"Create a text request body", {"json"}, "Create a json request body", {"json"},
New_JsonHttpRequestBody); New_JsonHttpRequestBody);
_new->DeclareFunction( _new->DeclareFunction(
gc, "HttpServer", "Create a http server (allows multiple)", gc, "HttpServer", "Create a http server (allows multiple)",
+1 -5
View File
@@ -3,10 +3,6 @@
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
class ProcessObject : public TNativeObject { class ProcessObject : public TNativeObject {
public: public:
ProcessObject() {
arguments = nullptr;
environment = nullptr;
}
ProcessObject(GCList &ls) { ProcessObject(GCList &ls) {
arguments = TList::Create(ls); arguments = TList::Create(ls);
environment = TList::Create(ls); environment = TList::Create(ls);
@@ -167,7 +163,7 @@ static TObject Process_Start(GCList &ls, std::vector<TObject> args,
TDictionary *dict; TDictionary *dict;
if (GetArgumentHeap(args, 0, dict)) { if (GetArgumentHeap(args, 0, dict)) {
auto process = TNativeObject::Create<ProcessObject>(ls); auto process = TNativeObject::Create<ProcessObject>(ls, ls);
auto name = dict->GetValue("FileName"); auto name = dict->GetValue("FileName");
auto inh = dict->GetValue("InheritParentEnvironment"); auto inh = dict->GetValue("InheritParentEnvironment");
auto rStdIn = dict->GetValue("RedirectStandardInput"); auto rStdIn = dict->GetValue("RedirectStandardInput");
+7 -1
View File
@@ -1613,7 +1613,13 @@ void TStd::RegisterStd(
gc_dict->DeclareFunction( gc_dict->DeclareFunction(
gc, "Collect", "Collect garbage", {}, gc, "Collect", "Collect garbage", {},
[](GCList &ls, std::vector<TObject> args) -> TObject { [](GCList &ls, std::vector<TObject> args) -> TObject {
ls.GetGC()->Collect(); std::vector<THeapObject *> to_delete;
ls.GetGC()->BarrierBegin();
ls.GetGC()->Collect(to_delete);
ls.GetGC()->BarrierEnd();
for (auto item : to_delete)
delete item;
return nullptr; return nullptr;
}); });
gc_dict->DeclareFunction( gc_dict->DeclareFunction(
+5
View File
@@ -67,6 +67,8 @@ static TObject VM_SourceToAst(GCList &ls, std::vector<TObject> args) {
static TObject VM_Eval(GCList &ls, std::vector<TObject> args) { static TObject VM_Eval(GCList &ls, std::vector<TObject> args) {
std::string str; std::string str;
if (GetArgument(args, 0, str)) { if (GetArgument(args, 0, str)) {
auto current_function = GC::GetCurrentFunction();
if (current_function != nullptr) { if (current_function != nullptr) {
return current_function->env->Eval(ls, str); return current_function->env->Eval(ls, str);
} }
@@ -90,6 +92,8 @@ static TObject Success(GCList &ls) {
} }
static TObject VM_getCurrentEnvironment(GCList &ls2, static TObject VM_getCurrentEnvironment(GCList &ls2,
std::vector<TObject> args) { std::vector<TObject> args) {
auto current_function = GC::GetCurrentFunction();
if (current_function != nullptr) if (current_function != nullptr)
return current_function->env; return current_function->env;
return Undefined(); return Undefined();
@@ -261,6 +265,7 @@ static TObject VM_Compile(GCList &ls, std::vector<TObject> args) {
} }
} }
static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) { static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) {
auto current_function = GC::GetCurrentFunction();
if (current_function != nullptr) { if (current_function != nullptr) {
if (current_function->thread != nullptr) { if (current_function->thread != nullptr) {
TList *list = TList::Create(ls); TList *list = TList::Create(ls);
+2 -16
View File
@@ -1,22 +1,8 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TAny *TAny::Create(GCList &ls) { TAny *TAny::Create(GCList &ls) { return ls.Create<TAny>(); }
TAny *anyObj = new TAny(); TAny *TAny::Create(GCList *ls) { return ls->Create<TAny>(); }
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(anyObj);
gc->Watch(anyObj);
return anyObj;
}
TAny *TAny::Create(GCList *ls) {
TAny *anyObj = new TAny();
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(anyObj);
gc->Watch(anyObj);
return anyObj;
}
void TAny::Mark() { void TAny::Mark() {
if (this->marked) if (this->marked)
return; return;
+2 -10
View File
@@ -3,18 +3,10 @@
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TAssociativeArray *TAssociativeArray::Create(GCList &ls) { TAssociativeArray *TAssociativeArray::Create(GCList &ls) {
TAssociativeArray *list = new TAssociativeArray(); return ls.Create<TAssociativeArray>();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(list);
_gc->Watch(list);
return list;
} }
TAssociativeArray *TAssociativeArray::Create(GCList *ls) { TAssociativeArray *TAssociativeArray::Create(GCList *ls) {
TAssociativeArray *list = new TAssociativeArray(); return ls->Create<TAssociativeArray>();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(list);
_gc->Watch(list);
return list;
} }
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key, void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key,
TObject value) { TObject value) {
+9 -12
View File
@@ -9,22 +9,12 @@ bool TClassEnvironment::HasConstForSet(std::string key) {
TClassEnvironment *TClassEnvironment::Create(GCList *gc, TEnvironment *env, TClassEnvironment *TClassEnvironment::Create(GCList *gc, TEnvironment *env,
TClassObject *obj) { TClassObject *obj) {
TClassEnvironment *env2 = new TClassEnvironment(env, obj); return gc->Create<TClassEnvironment>(env, obj);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(env2);
_gc->Watch(env2);
return env2;
} }
TClassEnvironment *TClassEnvironment::Create(GCList &gc, TEnvironment *env, TClassEnvironment *TClassEnvironment::Create(GCList &gc, TEnvironment *env,
TClassObject *obj) { TClassObject *obj) {
TClassEnvironment *env2 = new TClassEnvironment(env, obj); return gc.Create<TClassEnvironment>(env, obj);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(env2);
_gc->Watch(env2);
return env2;
} }
TClassEnvironment::TClassEnvironment(TEnvironment *env, TClassObject *obj) { TClassEnvironment::TClassEnvironment(TEnvironment *env, TClassObject *obj) {
this->env = env; this->env = env;
@@ -33,6 +23,7 @@ TClassEnvironment::TClassEnvironment(TEnvironment *env, TClassObject *obj) {
bool TClassEnvironment::HasVariable(std::string key) { bool TClassEnvironment::HasVariable(std::string key) {
if (key == "this") if (key == "this")
return true; return true;
auto current_function = GC::GetCurrentFunction();
if (this->clsObj->HasValue(current_function == nullptr if (this->clsObj->HasValue(current_function == nullptr
? "" ? ""
: current_function->callable->className, : current_function->callable->className,
@@ -49,6 +40,8 @@ bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key,
bool setting) { bool setting) {
if (key == "this") if (key == "this")
return true; return true;
auto current_function = GC::GetCurrentFunction();
std::string clsName = current_function == nullptr std::string clsName = current_function == nullptr
? "" ? ""
: current_function->callable->className; : current_function->callable->className;
@@ -63,6 +56,7 @@ TObject TClassEnvironment::GetVariable(std::string key) {
if (key == "this") if (key == "this")
return this->clsObj; return this->clsObj;
auto current_function = GC::GetCurrentFunction();
std::string clsName = current_function == nullptr std::string clsName = current_function == nullptr
? "" ? ""
: current_function->callable->className; : current_function->callable->className;
@@ -75,6 +69,7 @@ void TClassEnvironment::SetVariable(std::string key, TObject value) {
if (key == "this") if (key == "this")
return; return;
auto current_function = GC::GetCurrentFunction();
std::string clsName = current_function == nullptr std::string clsName = current_function == nullptr
? "" ? ""
: current_function->callable->className; : current_function->callable->className;
@@ -90,6 +85,7 @@ TObject TClassEnvironment::GetVariable(GCList &ls, std::string key) {
if (key == "this") if (key == "this")
return this->clsObj; return this->clsObj;
auto current_function = GC::GetCurrentFunction();
std::string clsName = current_function == nullptr std::string clsName = current_function == nullptr
? "" ? ""
: current_function->callable->className; : current_function->callable->className;
@@ -107,6 +103,7 @@ TObject TClassEnvironment::SetVariable(GCList &ls, std::string key, TObject v) {
if (key == "this") if (key == "this")
return this->clsObj; return this->clsObj;
auto current_function = GC::GetCurrentFunction();
std::string clsName = current_function == nullptr std::string clsName = current_function == nullptr
? "" ? ""
: current_function->callable->className; : current_function->callable->className;
+23 -45
View File
@@ -1,27 +1,18 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TArgWrapper::TArgWrapper(TCallable *callable) : callable(callable) {}
TArgWrapper *TArgWrapper::Create(GCList &ls, TCallable *callable) { TArgWrapper *TArgWrapper::Create(GCList &ls, TCallable *callable) {
TArgWrapper *argWrapper = new TArgWrapper(); return ls.Create<TArgWrapper>(callable);
argWrapper->callable = callable;
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
} }
TArgWrapper *TArgWrapper::Create(GCList *ls, TCallable *callable) { TArgWrapper *TArgWrapper::Create(GCList *ls, TCallable *callable) {
TArgWrapper *argWrapper = new TArgWrapper(); return ls->Create<TArgWrapper>(callable);
argWrapper->callable = callable;
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
} }
TObject TArgWrapper::Call(GCList &ls, std::vector<TObject> args) { TObject TArgWrapper::Call(GCList &ls, std::vector<TObject> args) {
auto cse = current_function; auto cse = GC::GetCurrentFunction();
TList *argList = TList::Create(ls); TList *argList = TList::Create(ls);
argList->items = args; argList->items = args;
TObject v = this->callable->Call(ls, {argList}); TObject v = this->callable->Call(ls, {argList});
current_function = cse; GC::SetCurrentFunction(cse);
return v; return v;
} }
void TArgWrapper::Mark() { void TArgWrapper::Mark() {
@@ -46,52 +37,39 @@ void TClosure::Mark() {
this->closure->Mark(); this->closure->Mark();
GC::Mark(this->tag); GC::Mark(this->tag);
} }
TClosure *TClosure::Create(GCList &ls, TEnvironment *env, TFile *file, TClosure::TClosure(TEnvironment *env, TFile *file, uint32_t chunkId,
uint32_t chunkId, bool ownScope) { bool ownScope) {
TClosure *closure = new TClosure(); this->className = "";
closure->className = ""; this->ownScope = ownScope;
closure->ownScope = ownScope;
std::shared_ptr<GC> _gc = ls.GetGC(); this->chunkId = chunkId;
ls.Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if (chunkId < file->chunks.size()) if (chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId]; this->closure = file->chunks[chunkId];
else else
throw VMException("ChunkId out of bounds."); throw VMException("ChunkId out of bounds.");
closure->env = env; this->env = env;
closure->file = file; this->file = file;
}
return closure; TClosure *TClosure::Create(GCList &ls, TEnvironment *env, TFile *file,
uint32_t chunkId, bool ownScope) {
return ls.Create<TClosure>(env, file, chunkId, ownScope);
} }
TClosure *TClosure::Create(GCList *ls, TEnvironment *env, TFile *file, TClosure *TClosure::Create(GCList *ls, TEnvironment *env, TFile *file,
uint32_t chunkId, bool ownScope) { uint32_t chunkId, bool ownScope) {
TClosure *closure = new TClosure(); return ls->Create<TClosure>(env, file, chunkId, ownScope);
closure->className = "";
closure->ownScope = ownScope;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if (chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId];
else
throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
} }
TObject TClosure::Call(GCList &ls, std::vector<TObject> args) { TObject TClosure::Call(GCList &ls, std::vector<TObject> args) {
auto cse = current_function; auto cse = GC::GetCurrentFunction();
InterperterThread *thrd = InterperterThread::Create(ls); InterperterThread *thrd = InterperterThread::Create(ls);
thrd->AddCallStackEntry(ls, this, args); thrd->AddCallStackEntry(ls, this, args);
thrd->Execute(ls.GetGC()); thrd->Execute(ls.GetGC());
TObject v = thrd->call_stack_entries[0]->Pop(ls); TObject v = thrd->call_stack_entries[0]->Pop(ls);
current_function = cse; GC::SetCurrentFunction(cse);
// current_function = cse;
return v; return v;
} }
} // namespace Tesses::CrossLang } // namespace Tesses::CrossLang
+8 -24
View File
@@ -1,24 +1,15 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TDynamicDictionary::TDynamicDictionary(TCallable *callable) : cb(callable) {}
TDynamicDictionary *TDynamicDictionary::Create(GCList &ls, TDynamicDictionary *TDynamicDictionary::Create(GCList &ls,
TCallable *callable) { TCallable *callable) {
TDynamicDictionary *dict = new TDynamicDictionary(); return ls.Create<TDynamicDictionary>(callable);
dict->cb = callable;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(dict);
_gc->Watch(dict);
return dict;
} }
TDynamicDictionary *TDynamicDictionary::Create(GCList *ls, TDynamicDictionary *TDynamicDictionary::Create(GCList *ls,
TCallable *callable) { TCallable *callable) {
TDynamicDictionary *dict = new TDynamicDictionary(); return ls->Create<TDynamicDictionary>(callable);
dict->cb = callable;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(dict);
_gc->Watch(dict);
return dict;
} }
void TDynamicDictionary::Mark() { void TDynamicDictionary::Mark() {
@@ -165,8 +156,9 @@ void TDictionary::DeclareFunction(
TObject TDictionary::GetValue(std::string key) { TObject TDictionary::GetValue(std::string key) {
if (this->items.empty()) if (this->items.empty())
return Undefined(); return Undefined();
if (this->items.count(key) > 0) auto item = this->items.find(key);
return this->items[key]; if (item != this->items.end())
return item->second;
return Undefined(); return Undefined();
} }
void TDictionary::SetValue(std::string key, TObject value) { void TDictionary::SetValue(std::string key, TObject value) {
@@ -189,18 +181,10 @@ void TDictionary::Mark() {
} }
} }
TDictionary *TDictionary::Create(GCList *gc) { TDictionary *TDictionary::Create(GCList *gc) {
TDictionary *dict = new TDictionary(); return gc->Create<TDictionary>();
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(dict);
_gc->Watch(dict);
return dict;
} }
TDictionary *TDictionary::Create(GCList &gc) { TDictionary *TDictionary::Create(GCList &gc) {
TDictionary *dict = new TDictionary(); return gc.Create<TDictionary>();
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(dict);
_gc->Watch(dict);
return dict;
} }
}; // namespace Tesses::CrossLang }; // namespace Tesses::CrossLang
+168
View File
@@ -0,0 +1,168 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TException::TException(std::string message, std::string type,
TDictionary *extraFields, TObject innerException)
: message(message), type(type), extraFields(extraFields),
innerException(innerException) {}
TObject TException::CallMethod(GCList &ls, std::string key,
std::vector<TObject> args) {
if (key == "getMessage" ||
key == "getText") // Text is for compatibility reasons
return this->message;
if (key == "getInnerException")
return this->innerException;
if (key == "getType")
return this->type;
if (key == "getLine")
return static_cast<int64_t>(this->line.value_or(0));
if (key == "getOffset")
return static_cast<int64_t>(this->offset.value_or(0));
if (key == "getColumn")
return static_cast<int64_t>(this->column.value_or(0));
if (key == "getFileName")
return this->filename.value_or("");
if (key == "setLine") {
int64_t v;
if (!this->line && GetArgument(args, 0, v))
this->line = static_cast<uint32_t>(v);
return Undefined();
}
if (key == "setColumn") {
int64_t v;
if (!this->column && GetArgument(args, 0, v))
this->column = static_cast<uint32_t>(v);
return Undefined();
}
if (key == "setOffset") {
int64_t v;
if (!this->offset && GetArgument(args, 0, v))
this->offset = static_cast<uint32_t>(v);
return Undefined();
}
if (key == "setFileName") {
std::string v;
if (!this->filename && GetArgument(args, 0, v))
this->filename = v;
return Undefined();
}
if (key == "ToString") {
std::string text;
text.reserve(this->type.size() + this->message.size() + 3);
text.append(this->type);
text.append(": ");
text.append(this->message);
text.push_back('\n');
if (this->filename) {
auto &filename = *this->filename;
text.reserve(text.size() + filename.size() + 4);
text.append("At: ");
text.append(filename);
if (this->line) {
text.push_back(':');
text.append(std::to_string(*this->line));
if (this->column) {
text.push_back(':');
text.append(std::to_string(*this->column));
}
}
text.push_back('\n');
if (!this->line && this->column) {
text.append("Column: ");
text.append(std::to_string(*this->column));
text.push_back('\n');
}
} else {
if (this->line) {
text.append("Line: ");
text.append(std::to_string(*this->line));
text.push_back('\n');
}
if (this->column) {
text.append("Column: ");
text.append(std::to_string(*this->column));
text.push_back('\n');
}
}
if (this->offset) {
text.append("Offset: ");
text.append(std::to_string(*this->offset));
text.push_back('\n');
}
if (!std::holds_alternative<Undefined>(this->innerException)) {
text.append("InnerException:");
std::string textInner = ToString(ls.GetGC(), this->innerException);
for (auto item : Tesses::Framework::Http::HttpUtils::SplitString(
textInner, "\n")) {
if (item.empty()) {
text.push_back('\n');
continue;
}
text.append("\n\t");
text.append(item);
}
}
return text;
}
if (extraFields != nullptr) {
GCList ls2(ls.GetGC());
if (extraFields->MethodExists(ls2, key)) {
return extraFields->CallMethod(ls, key, args);
}
if (key.size() > 3 && key[0] == 'g' && key[1] == 'e' && key[2] == 't') {
ls.GetGC()->BarrierBegin();
auto val = extraFields->GetValue(key.substr(3));
ls.GetGC()->BarrierEnd();
return val;
}
}
return Undefined();
}
std::string TException::TypeName() { return this->type; }
bool TException::ToBool() { return true; }
void TException::Mark() {
if (marked)
return;
marked = true;
if (this->extraFields)
this->extraFields->Mark();
GC::Mark(this->innerException);
}
TNativeException::TNativeException(const char *what, std::exception_ptr ptr)
: what(what != nullptr ? what : ""), ptr(ptr) {}
TObject TNativeException::CallMethod(GCList &ls, std::string key,
std::vector<TObject> args) {
if (key == "getMessage" || key == "getText")
return this->what;
if (key == "getType")
return "NativeException";
if (key == "ToString") {
return "NativeException: " + this->what;
}
return Undefined();
}
std::string TNativeException::TypeName() { return "NativeException"; }
std::string TNativeException::What() { return this->what; }
std::exception_ptr TNativeException::GetPointer() { return this->ptr; }
void TNativeException::ThrowIt() { std::rethrow_exception(this->ptr); }
} // namespace Tesses::CrossLang
+6 -25
View File
@@ -1,8 +1,8 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TExternalMethod::TExternalMethod( TExternalMethod::TExternalMethod(
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::string documentation, std::vector<std::string> argNames, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy) { std::function<void()> destroy) {
this->cb = cb; this->cb = cb;
@@ -14,43 +14,24 @@ TExternalMethod *TExternalMethod::Create(
GCList &ls, std::string documentation, std::vector<std::string> argNames, GCList &ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb, std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy) { std::function<void()> destroy) {
auto gc = ls.GetGC(); return ls.Create<TExternalMethod>(documentation, argNames, cb, destroy);
TExternalMethod *method =
new TExternalMethod(cb, documentation, argNames, destroy);
ls.Add(method);
gc->Watch(method);
return method;
} }
TExternalMethod *TExternalMethod::Create( TExternalMethod *TExternalMethod::Create(
GCList *ls, std::string documentation, std::vector<std::string> argNames, GCList *ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb, std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy) { std::function<void()> destroy) {
auto gc = ls->GetGC(); return ls->Create<TExternalMethod>(documentation, argNames, cb, destroy);
TExternalMethod *method =
new TExternalMethod(cb, documentation, argNames, destroy);
ls->Add(method);
gc->Watch(method);
return method;
} }
TExternalMethod *TExternalMethod::Create( TExternalMethod *TExternalMethod::Create(
GCList &ls, std::string documentation, std::vector<std::string> argNames, GCList &ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) { std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
auto gc = ls.GetGC(); return ls.Create<TExternalMethod>(documentation, argNames, cb);
TExternalMethod *method =
new TExternalMethod(cb, documentation, argNames, []() -> void {});
ls.Add(method);
gc->Watch(method);
return method;
} }
TExternalMethod *TExternalMethod::Create( TExternalMethod *TExternalMethod::Create(
GCList *ls, std::string documentation, std::vector<std::string> argNames, GCList *ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) { std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
auto gc = ls->GetGC();
TExternalMethod *method = return ls->Create<TExternalMethod>(documentation, argNames, cb);
new TExternalMethod(cb, documentation, argNames, []() -> void {});
ls->Add(method);
gc->Watch(method);
return method;
} }
TObject TExternalMethod::Call(GCList &ls, std::vector<TObject> args) { TObject TExternalMethod::Call(GCList &ls, std::vector<TObject> args) {
if (cb == nullptr) if (cb == nullptr)
+35 -114
View File
@@ -44,28 +44,15 @@ void TYieldEnumerator::Mark() {
GC::Mark(this->current); GC::Mark(this->current);
GC::Mark(this->enumerator); GC::Mark(this->enumerator);
} }
TYieldEnumerator *TYieldEnumerator::Create(GCList &ls, TObject v) {
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
yieldEnum->current = nullptr;
yieldEnum->hasStarted = false;
yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls.GetGC(); TYieldEnumerator::TYieldEnumerator(TObject v)
ls.Add(yieldEnum); : current(nullptr), hasStarted(false), enumerator(v) {}
_gc->Watch(yieldEnum);
return yieldEnum; TYieldEnumerator *TYieldEnumerator::Create(GCList &ls, TObject v) {
return ls.Create<TYieldEnumerator>(v);
} }
TYieldEnumerator *TYieldEnumerator::Create(GCList *ls, TObject v) { TYieldEnumerator *TYieldEnumerator::Create(GCList *ls, TObject v) {
return ls->Create<TYieldEnumerator>(v);
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
yieldEnum->current = nullptr;
yieldEnum->hasStarted = false;
yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(yieldEnum);
_gc->Watch(yieldEnum);
return yieldEnum;
} }
bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls) { bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls) {
@@ -97,21 +84,12 @@ void TCustomEnumerator::Mark() {
return; return;
this->dict->Mark(); this->dict->Mark();
} }
TCustomEnumerator::TCustomEnumerator(TDictionary *dict) : dict(dict) {}
TCustomEnumerator *TCustomEnumerator::Create(GCList *ls, TDictionary *dict) { TCustomEnumerator *TCustomEnumerator::Create(GCList *ls, TDictionary *dict) {
TCustomEnumerator *customEnum = new TCustomEnumerator(); return ls->Create<TCustomEnumerator>(dict);
customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
} }
TCustomEnumerator *TCustomEnumerator::Create(GCList &ls, TDictionary *dict) { TCustomEnumerator *TCustomEnumerator::Create(GCList &ls, TDictionary *dict) {
TCustomEnumerator *customEnum = new TCustomEnumerator(); return ls.Create<TCustomEnumerator>(dict);
customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
} }
TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) { TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) {
std::string str; std::string str;
@@ -141,23 +119,16 @@ TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) {
} }
return nullptr; return nullptr;
} }
TVFSPathEnumerator::TVFSPathEnumerator(
Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
: enumerator(enumerator) {}
TVFSPathEnumerator *TVFSPathEnumerator::Create( TVFSPathEnumerator *TVFSPathEnumerator::Create(
GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) { GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator(); return ls.Create<TVFSPathEnumerator>(enumerator);
vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
} }
TVFSPathEnumerator *TVFSPathEnumerator::Create( TVFSPathEnumerator *TVFSPathEnumerator::Create(
GCList *ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) { GCList *ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator(); return ls->Create<TVFSPathEnumerator>(enumerator);
vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
} }
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) { bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) {
return enumerator.MoveNext(); return enumerator.MoveNext();
@@ -165,25 +136,15 @@ bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) {
TObject TVFSPathEnumerator::GetCurrent(GCList &ls) { TObject TVFSPathEnumerator::GetCurrent(GCList &ls) {
return enumerator.Current; return enumerator.Current;
} }
TDictionaryEnumerator::TDictionaryEnumerator(TDictionary *dict)
: dict(dict), hasStarted(false) {}
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList &ls, TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList &ls,
TDictionary *dict) { TDictionary *dict) {
TDictionaryEnumerator *dicte = new TDictionaryEnumerator(); return ls.Create<TDictionaryEnumerator>(dict);
dicte->dict = dict;
dicte->hasStarted = false;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(dicte);
_gc->Watch(dicte);
return dicte;
} }
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList *ls, TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList *ls,
TDictionary *dict) { TDictionary *dict) {
TDictionaryEnumerator *dicte = new TDictionaryEnumerator(); return ls->Create<TDictionaryEnumerator>(dict);
dicte->dict = dict;
dicte->hasStarted = false;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(dicte);
_gc->Watch(dicte);
return dicte;
} }
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls) { bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls) {
@@ -217,24 +178,13 @@ void TDictionaryEnumerator::Mark() {
this->marked = true; this->marked = true;
this->dict->Mark(); this->dict->Mark();
} }
TListEnumerator::TListEnumerator(TList *list) : ls(list), index(-1) {}
TListEnumerator *TListEnumerator::Create(GCList &ls, TList *list) { TListEnumerator *TListEnumerator::Create(GCList &ls, TList *list) {
TListEnumerator *liste = new TListEnumerator(); return ls.Create<TListEnumerator>(list);
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
} }
TListEnumerator *TListEnumerator::Create(GCList *ls, TList *list) { TListEnumerator *TListEnumerator::Create(GCList *ls, TList *list) {
TListEnumerator *liste = new TListEnumerator(); return ls->Create<TListEnumerator>(list);
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
} }
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) { bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
this->index++; this->index++;
@@ -260,25 +210,17 @@ void TListEnumerator::Mark() {
this->ls->Mark(); this->ls->Mark();
} }
TAssociativeArrayEnumerator::TAssociativeArrayEnumerator(
TAssociativeArray *list)
: ls(list), index(-1) {}
TAssociativeArrayEnumerator * TAssociativeArrayEnumerator *
TAssociativeArrayEnumerator::Create(GCList &ls, TAssociativeArray *list) { TAssociativeArrayEnumerator::Create(GCList &ls, TAssociativeArray *list) {
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator(); return ls.Create<TAssociativeArrayEnumerator>(list);
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
} }
TAssociativeArrayEnumerator * TAssociativeArrayEnumerator *
TAssociativeArrayEnumerator::Create(GCList *ls, TAssociativeArray *list) { TAssociativeArrayEnumerator::Create(GCList *ls, TAssociativeArray *list) {
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator(); return ls->Create<TAssociativeArrayEnumerator>(list);
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
} }
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) { bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) {
this->index++; this->index++;
@@ -305,26 +247,16 @@ void TAssociativeArrayEnumerator::Mark() {
this->marked = true; this->marked = true;
this->ls->Mark(); this->ls->Mark();
} }
TDynamicListEnumerator::TDynamicListEnumerator(TDynamicList *list)
: ls(list), index(-1) {}
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList &ls, TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList &ls,
TDynamicList *list) { TDynamicList *list) {
TDynamicListEnumerator *liste = new TDynamicListEnumerator(); return ls.Create<TDynamicListEnumerator>(list);
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
} }
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList *ls, TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList *ls,
TDynamicList *list) { TDynamicList *list) {
TDynamicListEnumerator *liste = new TDynamicListEnumerator(); return ls->Create<TDynamicListEnumerator>(list);
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
} }
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) { bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
this->index++; this->index++;
@@ -351,24 +283,13 @@ void TDynamicListEnumerator::Mark() {
this->marked = true; this->marked = true;
this->ls->Mark(); this->ls->Mark();
} }
TStringEnumerator::TStringEnumerator(std::string str)
: str(str), hasStarted(false) {}
TStringEnumerator *TStringEnumerator::Create(GCList &ls, std::string str) { TStringEnumerator *TStringEnumerator::Create(GCList &ls, std::string str) {
TStringEnumerator *stre = new TStringEnumerator(); return ls.Create<TStringEnumerator>(str);
stre->str = str;
stre->hasStarted = false;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(stre);
_gc->Watch(stre);
return stre;
} }
TStringEnumerator *TStringEnumerator::Create(GCList *ls, std::string str) { TStringEnumerator *TStringEnumerator::Create(GCList *ls, std::string str) {
TStringEnumerator *stre = new TStringEnumerator(); return ls->Create<TStringEnumerator>(str);
stre->str = str;
stre->hasStarted = false;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(stre);
_gc->Watch(stre);
return stre;
} }
bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls) { bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls) {
if (!this->hasStarted) { if (!this->hasStarted) {
+8 -41
View File
@@ -1,20 +1,11 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TDynamicList::TDynamicList(TCallable *callable) : cb(callable) {}
TDynamicList *TDynamicList::Create(GCList &ls, TCallable *callable) { TDynamicList *TDynamicList::Create(GCList &ls, TCallable *callable) {
TDynamicList *list = new TDynamicList(); return ls.Create<TDynamicList>(callable);
list->cb = callable;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(list);
_gc->Watch(list);
return list;
} }
TDynamicList *TDynamicList::Create(GCList *ls, TCallable *callable) { TDynamicList *TDynamicList::Create(GCList *ls, TCallable *callable) {
TDynamicList *list = new TDynamicList(); return ls->Create<TDynamicList>(callable);
list->cb = callable;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(list);
_gc->Watch(list);
return list;
} }
void TDynamicList::Mark() { void TDynamicList::Mark() {
@@ -120,35 +111,11 @@ TObject TDynamicList::SetAt(GCList &ls, int64_t index, TObject val) {
TDynamicList::~TDynamicList() {} TDynamicList::~TDynamicList() {}
TByteArray *TByteArray::Create(GCList &ls) { TByteArray *TByteArray::Create(GCList &ls) { return ls.Create<TByteArray>(); }
TByteArray *arr = new TByteArray();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(arr);
_gc->Watch(arr);
return arr;
}
TByteArray *TByteArray::Create(GCList *ls) { TByteArray *TByteArray::Create(GCList *ls) { return ls->Create<TByteArray>(); }
TByteArray *arr = new TByteArray(); TList *TList::Create(GCList *gc) { return gc->Create<TList>(); }
std::shared_ptr<GC> _gc = ls->GetGC(); TList *TList::Create(GCList &gc) { return gc.Create<TList>(); }
ls->Add(arr);
_gc->Watch(arr);
return arr;
}
TList *TList::Create(GCList *gc) {
TList *list = new TList();
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(list);
_gc->Watch(list);
return list;
}
TList *TList::Create(GCList &gc) {
TList *list = new TList();
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(list);
_gc->Watch(list);
return list;
}
void TList::Add(TObject value) { this->items.push_back(value); } void TList::Add(TObject value) { this->items.push_back(value); }
void TList::Set(int64_t index, TObject value) { void TList::Set(int64_t index, TObject value) {
if (index >= 0 && index < this->Count()) { if (index >= 0 && index < this->Count()) {
@@ -161,7 +128,7 @@ TObject TList::Get(int64_t index) {
} }
return Undefined(); return Undefined();
} }
int64_t TList::Count() { return (int64_t)this->items.size(); } int64_t TList::Count() { return this->items.size(); }
void TList::Insert(int64_t index, TObject value) { void TList::Insert(int64_t index, TObject value) {
if (index >= 0 && index <= this->Count()) { if (index >= 0 && index <= this->Count()) {
this->items.insert(this->items.begin() + index, value); this->items.insert(this->items.begin() + index, value);
+2 -11
View File
@@ -1,7 +1,6 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TNativeObject::~TNativeObject() {}
TNative::TNative(void *ptr, std::function<void(void *)> destroy) { TNative::TNative(void *ptr, std::function<void(void *)> destroy) {
this->ptr = ptr; this->ptr = ptr;
@@ -34,19 +33,11 @@ bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right) {
} }
TNative *TNative::Create(GCList &ls, void *ptr, TNative *TNative::Create(GCList &ls, void *ptr,
std::function<void(void *)> destroy) { std::function<void(void *)> destroy) {
TNative *native = new TNative(ptr, destroy); return ls.Create<TNative>(ptr, destroy);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(native);
gc->Watch(native);
return native;
} }
TNative *TNative::Create(GCList *ls, void *ptr, TNative *TNative::Create(GCList *ls, void *ptr,
std::function<void(void *)> destroy) { std::function<void(void *)> destroy) {
TNative *native = new TNative(ptr, destroy); return ls->Create<TNative>(ptr, destroy);
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(native);
gc->Watch(native);
return native;
} }
TNative::~TNative() { this->Destroy(); } TNative::~TNative() { this->Destroy(); }
+2 -10
View File
@@ -41,19 +41,11 @@ TList *TQueryable::ToList(GCList &ls) {
return list; return list;
} }
TQueryable *TQueryable::Create(GCList &ls, TObject parent) { TQueryable *TQueryable::Create(GCList &ls, TObject parent) {
TQueryable *queryable = new TQueryable(parent); return ls.Create<TQueryable>(parent);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
} }
TQueryable *TQueryable::Create(GCList &ls, TObject parent, TQueryableMode mode, TQueryable *TQueryable::Create(GCList &ls, TObject parent, TQueryableMode mode,
std::vector<TObject> args) { std::vector<TObject> args) {
TQueryable *queryable = new TQueryable(parent, mode, args); return ls.Create<TQueryable>(parent, mode, args);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
} }
void TQueryable::Mark() { void TQueryable::Mark() {
+9 -16
View File
@@ -9,12 +9,11 @@ void ThrowConstError(std::string key) {
void TEnvironment::DeclareConstVariable(std::string key, TObject value) { void TEnvironment::DeclareConstVariable(std::string key, TObject value) {
this->DeclareVariable(key, value); this->DeclareVariable(key, value);
this->consts.push_back(key); this->decls[key] = TEnvironmentDeclType::TEDT_CONST;
} }
bool TEnvironment::HasConstForDeclare(std::string key) { bool TEnvironment::HasConstForDeclare(std::string key) {
for (auto item : this->consts) if (this->decls.count(key) > 0)
if (item == key) return this->decls[key] == TEnvironmentDeclType::TEDT_CONST;
return true;
return false; return false;
} }
bool TEnvironment::HasConstForSet(std::string key) { bool TEnvironment::HasConstForSet(std::string key) {
@@ -308,13 +307,15 @@ void TRootEnvironment::SetVariable(std::string key, TObject value) {
this->dict->SetValue(key, value); this->dict->SetValue(key, value);
} }
void TRootEnvironment::DeclareVariable(std::string key, TObject value) { void TRootEnvironment::DeclareVariable(std::string key, TObject value) {
if (this->decls.count(key) == 0)
this->decls[key] = TEnvironmentDeclType::TEDT_VAR;
return this->dict->SetValue(key, value); return this->dict->SetValue(key, value);
} }
bool TRootEnvironment::HasVariable(std::string key) { bool TRootEnvironment::HasVariable(std::string key) {
return this->dict->HasValue(key); return this->dict->HasValue(key) || this->decls.count(key) > 0;
} }
bool TRootEnvironment::HasVariableRecurse(std::string key) { bool TRootEnvironment::HasVariableRecurse(std::string key) {
return this->dict->HasValue(key); return this->dict->HasValue(key) || this->decls.count(key) > 0;
} }
TEnvironment *TRootEnvironment::GetParentEnvironment() { return this; } TEnvironment *TRootEnvironment::GetParentEnvironment() { return this; }
TRootEnvironment *TRootEnvironment::GetRootEnvironment() { return this; } TRootEnvironment *TRootEnvironment::GetRootEnvironment() { return this; }
@@ -338,18 +339,10 @@ void TRootEnvironment::Mark() {
cls.first->Mark(); cls.first->Mark();
} }
TRootEnvironment *TRootEnvironment::Create(GCList *gc, TDictionary *dict) { TRootEnvironment *TRootEnvironment::Create(GCList *gc, TDictionary *dict) {
TRootEnvironment *env = new TRootEnvironment(dict); return gc->Create<TRootEnvironment>(dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(env);
_gc->Watch(env);
return env;
} }
TRootEnvironment *TRootEnvironment::Create(GCList &gc, TDictionary *dict) { TRootEnvironment *TRootEnvironment::Create(GCList &gc, TDictionary *dict) {
TRootEnvironment *env = new TRootEnvironment(dict); return gc.Create<TRootEnvironment>(dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(env);
_gc->Watch(env);
return env;
} }
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc, bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,
+13 -13
View File
@@ -82,16 +82,24 @@ TObject TSubEnvironment::GetVariable(std::string key) {
if (this->dict->HasValue(key)) { if (this->dict->HasValue(key)) {
return this->dict->GetValue(key); return this->dict->GetValue(key);
} }
if (this->decls.count(key) > 0 &&
this->decls[key] == TEnvironmentDeclType::TEDT_VAR) {
return Undefined();
}
if (this->env->HasVariableRecurse(key)) { if (this->env->HasVariableRecurse(key)) {
return this->env->GetVariable(key); return this->env->GetVariable(key);
} }
return Undefined(); return Undefined();
} }
void TSubEnvironment::DeclareVariable(std::string key, TObject value) { void TSubEnvironment::DeclareVariable(std::string key, TObject value) {
if (this->decls.count(key) == 0)
this->decls[key] = TEnvironmentDeclType::TEDT_VAR;
this->dict->SetValue(key, value); this->dict->SetValue(key, value);
} }
void TSubEnvironment::SetVariable(std::string key, TObject value) { void TSubEnvironment::SetVariable(std::string key, TObject value) {
if (this->dict->HasValue(key)) {
if (this->dict->HasValue(key) || this->decls.count(key) > 0) {
this->dict->SetValue(key, value); this->dict->SetValue(key, value);
return; return;
} }
@@ -102,10 +110,10 @@ void TSubEnvironment::SetVariable(std::string key, TObject value) {
} }
} }
bool TSubEnvironment::HasVariable(std::string key) { bool TSubEnvironment::HasVariable(std::string key) {
return this->dict->HasValue(key); return this->dict->HasValue(key) || this->decls.count(key) > 0;
} }
bool TSubEnvironment::HasVariableRecurse(std::string key) { bool TSubEnvironment::HasVariableRecurse(std::string key) {
if (this->dict->HasValue(key)) if (this->dict->HasValue(key) || this->decls.count(key) > 0)
return true; return true;
return this->env->HasVariableRecurse(key); return this->env->HasVariableRecurse(key);
} }
@@ -159,19 +167,11 @@ TSubEnvironment *TEnvironment::GetSubEnvironment(GCList &gc) {
} }
TSubEnvironment *TSubEnvironment::Create(GCList *gc, TEnvironment *env, TSubEnvironment *TSubEnvironment::Create(GCList *gc, TEnvironment *env,
TDictionary *dict) { TDictionary *dict) {
TSubEnvironment *senv = new TSubEnvironment(env, dict); return gc->Create<TSubEnvironment>(env, dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(senv);
_gc->Watch(senv);
return senv;
} }
TSubEnvironment *TSubEnvironment::Create(GCList &gc, TEnvironment *env, TSubEnvironment *TSubEnvironment::Create(GCList &gc, TEnvironment *env,
TDictionary *dict) { TDictionary *dict) {
TSubEnvironment *senv = new TSubEnvironment(env, dict); return gc.Create<TSubEnvironment>(env, dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(senv);
_gc->Watch(senv);
return senv;
} }
TEnvironment *TSubEnvironment::GetParentEnvironment() { return this->env; } TEnvironment *TSubEnvironment::GetParentEnvironment() { return this->env; }
TRootEnvironment *TSubEnvironment::GetRootEnvironment() { TRootEnvironment *TSubEnvironment::GetRootEnvironment() {
+2 -2
View File
@@ -1490,12 +1490,12 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
pattern, pattern,
callable->ToRouteServerRequestHandler(gc)); callable->ToRouteServerRequestHandler(gc));
} }
} else if (key == "Trace") { } else if (key == "Query") {
std::string pattern; std::string pattern;
TCallable *callable; TCallable *callable;
if (GetArgument(args, 0, pattern) && if (GetArgument(args, 0, pattern) &&
GetArgumentHeap(args, 1, callable)) { GetArgumentHeap(args, 1, callable)) {
routable->Trace( routable->Query(
pattern, pattern,
callable->ToRouteServerRequestHandler(gc)); callable->ToRouteServerRequestHandler(gc));
} }
+4 -4
View File
@@ -58,13 +58,13 @@ void ThrowFatalError(std::exception &ex) {
error.WriteLine(text); error.WriteLine(text);
} }
exit(1); std::exit(1);
} }
if (clrtexcept != nullptr) { if (clrtexcept != nullptr) {
error.WriteLine("CrossLang has encountered a fatal runtime exception"); error.WriteLine("CrossLang has encountered a fatal runtime exception");
error.WriteLine(); error.WriteLine();
error.WriteLine(clrtexcept->what()); error.WriteLine(clrtexcept->what());
exit(1); std::exit(1);
} }
if (compiler != nullptr) { if (compiler != nullptr) {
error.WriteLine("CrossLang has encountered a compiler error"); error.WriteLine("CrossLang has encountered a compiler error");
@@ -81,13 +81,13 @@ void ThrowFatalError(std::exception &ex) {
error.Write(":"); error.Write(":");
error.WriteLine((int64_t)li.offset); error.WriteLine((int64_t)li.offset);
exit(1); std::exit(1);
} }
error.WriteLine("CrossLang has encountered a fatal C++ exception"); error.WriteLine("CrossLang has encountered a fatal C++ exception");
error.WriteLine(); error.WriteLine();
error.Write("what(): "); error.Write("what(): ");
error.WriteLine(ex2->what()); error.WriteLine(ex2->what());
exit(1); std::exit(1);
} }
} // namespace Tesses::CrossLang } // namespace Tesses::CrossLang
+4 -30
View File
@@ -5,22 +5,8 @@
#include <iostream> #include <iostream>
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TFile *TFile::Create(GCList &ls) { TFile *TFile::Create(GCList &ls) { return ls.Create<TFile>(); }
TFile *f = new TFile(); TFile *TFile::Create(GCList *ls) { return ls->Create<TFile>(); }
f->icon = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(f);
_gc->Watch(f);
return f;
}
TFile *TFile::Create(GCList *ls) {
TFile *f = new TFile();
f->icon = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(f);
_gc->Watch(f);
return f;
}
void TFileChunk::Mark() { void TFileChunk::Mark() {
if (this->marked) if (this->marked)
return; return;
@@ -28,20 +14,8 @@ void TFileChunk::Mark() {
this->file->Mark(); this->file->Mark();
} }
TFileChunk *TFileChunk::Create(GCList &ls) { TFileChunk *TFileChunk::Create(GCList &ls) { return ls.Create<TFileChunk>(); }
TFileChunk *chk = new TFileChunk(); TFileChunk *TFileChunk::Create(GCList *ls) { return ls->Create<TFileChunk>(); }
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(chk);
_gc->Watch(chk);
return chk;
}
TFileChunk *TFileChunk::Create(GCList *ls) {
TFileChunk *chk = new TFileChunk();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(chk);
_gc->Watch(chk);
return chk;
}
void TFile::Mark() { void TFile::Mark() {
if (this->marked) if (this->marked)
return; return;
+87 -79
View File
@@ -11,7 +11,18 @@
using namespace Tesses::Framework::Threading; using namespace Tesses::Framework::Threading;
using namespace std::chrono; using namespace std::chrono;
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
#if defined(GEKKO) || defined(_EE)
struct PthreadCmp {
bool operator()(const pthread_t &a, const pthread_t &b) const {
return pthread_equal(a, b) != 0;
}
};
static std::map<pthread_t, CallStackEntry *, PthreadCmp> current_funcs;
static Tesses::Framework::Threading::Mutex current_funcs_mtx;
#else
thread_local CallStackEntry *current_function;
#endif
bool GC::IsRunning() { bool GC::IsRunning() {
bool run = this->running; bool run = this->running;
@@ -74,7 +85,14 @@ TDictionary *CreateThread(GCList &ls, TCallable *callable, bool detached) {
TObject cb = th->callable->Call(ls, {}); TObject cb = th->callable->Call(ls, {});
gc->BarrierBegin(); gc->BarrierBegin();
th->returnValue = cb; th->returnValue = cb;
std::map<pthread_t, int> mt;
#if defined(GEKKO) || defined(_EE)
current_funcs_mtx.Lock();
current_funcs.erase(pthread_self());
current_funcs_mtx.Unlock();
#endif
gc->BarrierEnd(); gc->BarrierEnd();
th->hasReturned = true; th->hasReturned = true;
}); });
while (!th->hasInit) while (!th->hasInit)
@@ -93,50 +111,47 @@ void GC::Start() {
return new Tesses::Framework::Threading::ThreadPool(threads); return new Tesses::Framework::Threading::ThreadPool(threads);
}, },
[](Tesses::Framework::Threading::ThreadPool *p) -> void { delete p; }); [](Tesses::Framework::Threading::ThreadPool *p) -> void { delete p; });
this->mtx = new Mutex();
this->running = true; this->running = true;
this->thrd = new Thread([this]() -> void { this->thrd = new Thread([this]() -> void {
std::chrono::time_point<std::chrono::system_clock> last_frame,
this_frame;
this_frame = system_clock::now();
last_frame = this_frame;
while (this->IsRunning()) { while (this->IsRunning()) {
this_frame = system_clock::now(); this->BarrierBegin();
if ((this_frame - last_frame) > 10s) { while (this->allocs < ALLOC_THRESHOLD)
this->cond.Wait(
&this->mtx); // your wrapper around pthread_cond_wait
this->allocs = 0;
std::vector<THeapObject *> to_delete;
this->Collect(to_delete);
this->BarrierEnd();
last_frame = this_frame; for (auto o : to_delete)
this->Collect(); delete o;
} }
{
std::vector<THeapObject *> to_delete;
this->BarrierBegin();
this->Collect(to_delete);
this->BarrierEnd();
#if defined(_WIN32) for (auto item : to_delete)
Sleep(100); delete item;
#else
usleep(100000);
#endif
} }
GC::Collect();
}); });
} }
bool GC::UsingNullThreads() { return false; } bool GC::UsingNullThreads() { return false; }
void GC::BarrierBegin() { this->mtx->Lock(); } void GC::BarrierBegin() { this->mtx.Lock(); }
void GC::BarrierEnd() { this->mtx->Unlock(); } void GC::BarrierEnd() { this->mtx.Unlock(); }
void GC::Watch(TObject obj) { void GC::Watch(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) { if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj; auto _item = std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin(); this->BarrierBegin();
this->objects.insert(_item);
for (auto item : this->objects) { auto nowAllocs = ++this->allocs;
if (item == _item) {
this->BarrierEnd();
return;
}
}
this->objects.push_back(_item);
this->BarrierEnd(); this->BarrierEnd();
if (nowAllocs >= ALLOC_THRESHOLD)
this->cond.Signal();
} }
} }
void GC::Mark(TObject obj) { void GC::Mark(TObject obj) {
@@ -149,65 +164,36 @@ void GC::Unwatch(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) { if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj; auto _item = std::get<THeapObjectHolder>(obj).obj;
this->BarrierBegin(); this->BarrierBegin();
for (auto index = this->objects.begin(); this->objects.erase(_item);
index != this->objects.end();) {
if (*index == _item) {
index = this->objects.erase(index);
continue;
}
index++;
}
this->BarrierEnd(); this->BarrierEnd();
} }
} }
void GC::SetRoot(TObject obj) { void GC::SetRoot(GCList *_item) {
if (std::holds_alternative<THeapObjectHolder>(obj)) { if (_item == nullptr)
auto _item = std::get<THeapObjectHolder>(obj).obj; return;
this->BarrierBegin(); this->BarrierBegin();
for (auto item : this->roots) { this->roots.insert(_item);
if (item == _item) { this->BarrierEnd();
this->BarrierEnd();
return;
}
}
this->roots.push_back(_item);
this->BarrierEnd();
}
} }
Tesses::Framework::Threading::ThreadPool *GC::GetPool() { Tesses::Framework::Threading::ThreadPool *GC::GetPool() {
return this->tpool->GetValue(); return this->tpool->GetValue();
} }
void GC::UnsetRoot(TObject obj) { void GC::UnsetRoot(GCList *_item) {
if (std::holds_alternative<THeapObjectHolder>(obj)) { if (_item == nullptr)
auto _item = std::get<THeapObjectHolder>(obj).obj; return;
this->BarrierBegin(); this->BarrierBegin();
for (auto index = this->roots.begin(); index != this->roots.end();) { this->roots.erase(_item);
if (*index == _item) { this->BarrierEnd();
index = this->roots.erase(index);
continue;
}
index++;
}
this->BarrierEnd();
}
} }
GC::~GC() { GC::~GC() {
GC::BarrierBegin();
this->roots.clear();
GC::BarrierEnd();
this->running = false; this->running = false;
this->cond.Signal();
this->thrd->Join(); this->thrd->Join();
delete this->thrd; delete this->thrd;
for (auto item : objects)
delete item;
delete this->tpool; delete this->tpool;
delete this->mtx;
} }
void GC::RegisterEverythingCallback( void GC::RegisterEverythingCallback(
@@ -218,23 +204,45 @@ void GC::RegisterEverything(TRootEnvironment *env) {
for (auto item : this->register_everything) for (auto item : this->register_everything)
item(this->shared_from_this(), env); item(this->shared_from_this(), env);
} }
void GC::Collect() {
this->BarrierBegin(); CallStackEntry *GC::GetCurrentFunction() {
#if defined(GEKKO) || defined(_EE)
current_funcs_mtx.Lock();
auto val = current_funcs[pthread_self()];
current_funcs_mtx.Unlock();
return val;
#else
return current_function;
#endif
}
void GC::SetCurrentFunction(CallStackEntry *cse) {
#if defined(GEKKO) || defined(_EE)
current_funcs_mtx.Lock();
current_funcs[pthread_self()] = cse;
current_funcs_mtx.Unlock();
#else
current_function = cse;
#endif
}
void GC::Collect(std::vector<THeapObject *> &to_delete) {
for (auto item : this->objects) { for (auto item : this->objects) {
item->marked = false; item->marked = false;
} }
for (auto item : this->roots) { for (auto item : this->roots) {
item->Mark(); item->Mark();
} }
for (auto index = this->objects.begin(); index != this->objects.end(); for (auto index = this->objects.begin(); index != this->objects.end();) {
index++) {
THeapObject *o = *index; THeapObject *o = *index;
if (!o->marked) { if (!o->marked) {
delete o; to_delete.push_back(o);
this->objects.erase(index); index = this->objects.erase(index);
index--; } else {
++index;
} }
} }
this->BarrierEnd();
} }
}; // namespace Tesses::CrossLang }; // namespace Tesses::CrossLang
+1 -2
View File
@@ -8,7 +8,7 @@ GCList::GCList(std::shared_ptr<GC> gc) {
gc->BarrierEnd(); gc->BarrierEnd();
} }
std::shared_ptr<GC> GCList::GetGC() { return this->gc; } std::shared_ptr<GC> GCList::GetGC() const { return this->gc; }
void GCList::Remove(TObject obj) { void GCList::Remove(TObject obj) {
if (std::holds_alternative<THeapObjectHolder>(obj)) { if (std::holds_alternative<THeapObjectHolder>(obj)) {
auto _item = std::get<THeapObjectHolder>(obj).obj; auto _item = std::get<THeapObjectHolder>(obj).obj;
@@ -40,7 +40,6 @@ void GCList::Add(TObject obj) {
} }
} }
void GCList::Mark() { void GCList::Mark() {
this->marked = true;
for (auto item : this->items) { for (auto item : this->items) {
item->Mark(); item->Mark();
} }
+69 -55
View File
@@ -12,8 +12,6 @@
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
thread_local CallStackEntry *current_function = nullptr;
TObject ExecuteFunction(GCList &ls, TCallable *callable, TObject ExecuteFunction(GCList &ls, TCallable *callable,
std::vector<TObject> args) { std::vector<TObject> args) {
return callable->Call(ls, args); return callable->Call(ls, args);
@@ -2113,8 +2111,14 @@ bool InterperterThread::Throw(std::shared_ptr<GC> gc) {
if (!std::holds_alternative<Undefined>(_res2)) { if (!std::holds_alternative<Undefined>(_res2)) {
auto env = cse.back()->env; auto env = cse.back()->env;
if (!env->GetRootEnvironment()->HandleException(gc, env, _res2)) if (!env->GetRootEnvironment()->HandleException(gc, env, _res2)) {
TNativeException *nex;
if (GetObjectHeap(_res2, nex)) {
nex->ThrowIt();
}
throw VMByteCodeException(gc, _res2, cse.back()); throw VMByteCodeException(gc, _res2, cse.back());
}
} }
return false; return false;
} }
@@ -2223,6 +2227,7 @@ bool InterperterThread::JumpUndefined(std::shared_ptr<GC> gc) {
bool InterperterThread::Jump(std::shared_ptr<GC> gc) { bool InterperterThread::Jump(std::shared_ptr<GC> gc) {
std::vector<CallStackEntry *> &cse = this->call_stack_entries; std::vector<CallStackEntry *> &cse = this->call_stack_entries;
auto stk = cse.back(); auto stk = cse.back();
if (stk->ip + 4 <= stk->callable->closure->code.size()) { if (stk->ip + 4 <= stk->callable->closure->code.size()) {
@@ -2409,23 +2414,39 @@ bool InterperterThread::TryCatch(std::shared_ptr<GC> gc) {
if (GetObjectHeap(tryFn, tryC) && GetObjectHeap(catchFn, catchC)) { if (GetObjectHeap(tryFn, tryC) && GetObjectHeap(catchFn, catchC)) {
try { try {
stk->Push(gc, tryC->Call(ls, {})); stk->Push(gc, tryC->Call(ls, {}));
}
catch (std::exception &ex) { } catch (std::bad_alloc &ex) {
TDictionary *dict = TDictionary::Create(ls); std::cerr
auto gc = ls.GetGC(); << "CrossLang has failed to allocate, sorry for termination."
auto myEx = dynamic_cast<VMByteCodeException *>(&ex); << std::endl;
if (myEx != nullptr) { std::exit(1);
stk->Push(gc, catchC->Call(ls, {myEx->exception})); } catch (const std::string &ex) {
} else { stk->Push(gc, catchC->Call(ls, {ex}));
gc->BarrierBegin(); } catch (const char *ex) {
dict->SetValue("Type", "NativeException"); stk->Push(gc,
dict->SetValue("Text", ex.what()); catchC->Call(ls, {std::string{ex != nullptr ? ex : ""}}));
gc->BarrierEnd(); } catch (std::runtime_error &ex) {
stk->Push(gc, catchC->Call(ls, {dict})); stk->Push(
} gc, catchC->Call(ls, {TNativeObject::Create<TException>(
ls, ex.what(), "RuntimeException")}));
} catch (VMException &ex) {
stk->Push(
gc, catchC->Call(ls, {TNativeObject::Create<TException>(
ls, ex.GetMessage(), "VMException")}));
} catch (VMByteCodeException &ex) {
stk->Push(gc, catchC->Call(ls, {ex.exception}));
} catch (std::exception &ex) {
stk->Push(gc,
catchC->Call(
ls, {TNativeObject::Create<TNativeException>(
ls, ex.what(), std::current_exception())}));
} catch (...) {
stk->Push(gc,
catchC->Call(ls, {TNativeObject::Create<TNativeException>(
ls, "<No Message>",
std::current_exception())}));
} }
} }
return false; return false;
@@ -2693,14 +2714,14 @@ void InterperterThread::Execute(std::shared_ptr<GC> gc) {
std::vector<CallStackEntry *> &cse = this->call_stack_entries; std::vector<CallStackEntry *> &cse = this->call_stack_entries;
#define VM_OPCODE_TABLE_INLINE #define VM_OPCODE_TABLE_INLINE
#include "vm_opcode_table.h" #include "vm_opcode_table.def"
#undef VM_OPCODE_TABLE_INLINE #undef VM_OPCODE_TABLE_INLINE
execute: execute:
if (!cse.empty()) { if (!cse.empty()) {
auto stk = cse.back(); auto stk = cse.back();
current_function = stk; GC::SetCurrentFunction(stk);
try { try {
while (stk->ip < 0xFFFFFFFF && while (stk->ip < 0xFFFFFFFF &&
@@ -2721,7 +2742,7 @@ execute:
cse[cse.size() - 2]->Push(gc, o); cse[cse.size() - 2]->Push(gc, o);
cse.erase(cse.end() - 1); cse.erase(cse.end() - 1);
current_function = cse.back(); GC::SetCurrentFunction(cse.back());
gc->BarrierEnd(); gc->BarrierEnd();
goto execute; goto execute;
} else { } else {
@@ -2729,8 +2750,13 @@ execute:
} }
} }
if (gc->UsingNullThreads()) if (gc->UsingNullThreads()) {
gc->Collect(); std::vector<THeapObject *> objs;
gc->Collect(objs);
for (auto &item : objs) {
delete item;
}
}
} }
stk->mustReturn = false; stk->mustReturn = false;
@@ -2764,7 +2790,7 @@ execute:
} }
if (cse.size() == 1) { if (cse.size() == 1) {
current_function = nullptr; GC::SetCurrentFunction(nullptr);
{ {
gc->BarrierBegin(); gc->BarrierBegin();
@@ -2817,7 +2843,7 @@ execute:
cse[cse.size() - 2]->Push(gc, o); cse[cse.size() - 2]->Push(gc, o);
cse.erase(cse.end() - 1); cse.erase(cse.end() - 1);
current_function = cse.back(); GC::SetCurrentFunction(cse.back());
gc->BarrierEnd(); gc->BarrierEnd();
for (auto item : callable) { for (auto item : callable) {
@@ -2846,7 +2872,7 @@ void CallStackEntry::Push(std::shared_ptr<GC> gc, TObject o) {
gc->BarrierEnd(); gc->BarrierEnd();
} }
TObject CallStackEntry::Resume(GCList &ls) { TObject CallStackEntry::Resume(GCList &ls) {
auto cse = current_function; auto cse = GC::GetCurrentFunction();
InterperterThread *thrd = InterperterThread::Create(ls); InterperterThread *thrd = InterperterThread::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
thrd->call_stack_entries.push_back(this); thrd->call_stack_entries.push_back(this);
@@ -2855,7 +2881,7 @@ TObject CallStackEntry::Resume(GCList &ls) {
thrd->Execute(ls.GetGC()); thrd->Execute(ls.GetGC());
TObject v = thrd->call_stack_entries[0]->Pop(ls); TObject v = thrd->call_stack_entries[0]->Pop(ls);
current_function = cse; GC::SetCurrentFunction(cse);
return v; return v;
} }
TObject CallStackEntry::Pop(GCList &gc) { TObject CallStackEntry::Pop(GCList &gc) {
@@ -2870,41 +2896,17 @@ TObject CallStackEntry::Pop(GCList &gc) {
} }
InterperterThread *InterperterThread::Create(GCList &ls) { InterperterThread *InterperterThread::Create(GCList &ls) {
InterperterThread *it = new InterperterThread(); return ls.Create<InterperterThread>();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(it);
_gc->Watch(it);
return it;
} }
InterperterThread *InterperterThread::Create(GCList *ls) { InterperterThread *InterperterThread::Create(GCList *ls) {
InterperterThread *it = new InterperterThread(); return ls->Create<InterperterThread>();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(it);
_gc->Watch(it);
return it;
} }
CallStackEntry *CallStackEntry::Create(GCList &ls) { CallStackEntry *CallStackEntry::Create(GCList &ls) {
CallStackEntry *cse = new CallStackEntry(); return ls.Create<CallStackEntry>();
cse->mustReturn = false;
cse->srcline = -1;
cse->srcfile = "";
cse->thread = nullptr;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(cse);
_gc->Watch(cse);
return cse;
} }
CallStackEntry *CallStackEntry::Create(GCList *ls) { CallStackEntry *CallStackEntry::Create(GCList *ls) {
CallStackEntry *cse = new CallStackEntry(); return ls->Create<CallStackEntry>();
cse->mustReturn = false;
cse->srcline = -1;
cse->srcfile = "";
cse->thread = nullptr;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(cse);
_gc->Watch(cse);
return cse;
} }
void InterperterThread::AddCallStackEntry(GCList &ls, TClosure *closure, void InterperterThread::AddCallStackEntry(GCList &ls, TClosure *closure,
std::vector<TObject> args) { std::vector<TObject> args) {
@@ -2963,6 +2965,18 @@ void InterperterThread::AddCallStackEntry(GCList &ls, TClosure *closure,
cse->env->DeclareVariable(trimStart(closure->closure->args[i]), cse->env->DeclareVariable(trimStart(closure->closure->args[i]),
args[i]); args[i]);
} }
for (; i < closure->closure->args.size(); i++) {
auto &a = closure->closure->args[i];
if (a.size() > 1 && a[0] == '$') {
if (a[1] == '$') {
break;
}
cse->env->DeclareVariable(trimStart(a), Undefined());
} else {
break;
}
}
std::string back = closure->closure->args.empty() std::string back = closure->closure->args.empty()
? std::string() ? std::string()
: closure->closure->args.back(); : closure->closure->args.back();
@@ -2979,7 +2993,7 @@ void InterperterThread::AddCallStackEntry(GCList &ls, TClosure *closure,
throw VMException("Too many arguments"); throw VMException("Too many arguments");
} }
current_function = cse; GC::SetCurrentFunction(cse);
this->call_stack_entries.push_back(cse); this->call_stack_entries.push_back(cse);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();