10 Commits
54 changed files with 1291 additions and 953 deletions
+44 -15
View File
@@ -5,6 +5,7 @@ on:
- 'v*' - 'v*'
env: env:
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
@@ -12,23 +13,14 @@ env:
GITEA_REGISTRY_USER: tesses50 GITEA_REGISTRY_USER: tesses50
jobs: jobs:
build-arch: build-ppc:
runs-on: arch-builder name: "🔨 Build for PowerPC"
runs-on: ubuntu-latest
container:
image: git.tesses.org/tesses50/linux-ppc:latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: wget -O /root/repository.key https://git.tesses.org/api/packages/tesses50/arch/repository.key - run: bash build-for-ppc.sh
- run: pacman-key --add /root/repository.key
- run: pacman-key --config /opt/cross/ppc/pacman.conf --add /root/repository.key
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /etc/pacman.conf
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /opt/cross/ppc/pacman.conf
- run: pacman --noconfirm -Sy mbedtls tessesframework zip zig ninja
- run: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls tessesframework
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
- run: cp Packaging/Linux/build-arch.sh /home/build/build-arch.sh
- run: chmod 755 /home/build/build-arch.sh
- run: chown build:build /home/build/PKGBUILD
- run: chown build:build /home/build/build-arch.sh
- run: su build -c /home/build/build-arch.sh
- uses: akkuman/gitea-release-action@v1 - uses: akkuman/gitea-release-action@v1
env: env:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18 NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
@@ -36,6 +28,43 @@ jobs:
prerelease: true prerelease: true
files: |- files: |-
artifacts/** artifacts/**
build-packages:
name: "🔨 Build for everything else"
runs-on: fw13-ubuntu-latest
strategy:
fail-fast: true
matrix:
include:
- container: "git.tesses.org/tesses50/linux-x64:latest"
nfpmName: "amd64"
debianName: "x86_64-linux-gnu"
- container: "git.tesses.org/tesses50/linux-x86:latest"
nfpmName: "386"
debianName: "i386-linux-gnu"
- container: "git.tesses.org/tesses50/linux-arm:latest"
nfpmName: "arm7"
debianName: "arm-linux-gnueabihf"
- container: "git.tesses.org/tesses50/linux-arm64:latest"
nfpmName: "arm64"
debianName: "aarch64-linux-gnu"
- container: "git.tesses.org/tesses50/linux-riscv64:latest"
nfpmName: "riscv64"
debianName: "riscv64-linux-gnu"
container:
image: ${{ matrix.container }}
steps:
- uses: actions/checkout@v4
- run: bash build-for-nfpm.sh ${{ matrix.nfpmName }} ${{ matrix.debianName }}
- uses: akkuman/gitea-release-action@v1
env:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
with:
prerelease: true
files: |-
artifacts/**
update-tap: update-tap:
runs-on: global-container-mingw runs-on: global-container-mingw
+9
View File
@@ -32,4 +32,13 @@ include(cmake/app.cmake)
if(CROSSLANG_INSTALL_DEVELOPMENT) if(CROSSLANG_INSTALL_DEVELOPMENT)
add_subdirectory(pkgconfig) add_subdirectory(pkgconfig)
endif()
if(NOT CROSSLANG_TF_VERSION STREQUAL "")
if(NOT CROSSLANG_NFPM_ARCH STREQUAL "")
configure_file(nfpm.yaml.in nfpm.yaml @ONLY)
endif()
configure_file(ppc-pkgbuild.in ppc-pkgbuild @ONLY)
endif() endif()
-51
View File
@@ -1,51 +0,0 @@
# Maintainer: Mike Nolan <tesses@tesses.net>
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
pkgver=0.0.6
pkgrel=1
pkgdesc=""
arch=('x86_64' 'powerpc')
url="https://git.tesses.org/tesses50/crosslang"
license=('GPLv3')
groups=()
depends=('mbedtls' 'tessesframework=0.0.4')
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
install=
source=('crosslang::git+https://git.tesses.org/tesses50/crosslang')
noextract=()
sha256sums=('SKIP')
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
options=(!strip)
else
options=(!buildflags !strip)
fi
# Please refer to the 'USING VCS SOURCES' section of the PKGBUILD man page for
# a description of each element in the source array.
prepare() {
cd "$srcdir/${pkgname}"
}
build() {
cd "$srcdir/${pkgname}"
mkdir build
cd build
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release
else
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
fi
make -j`nproc`
}
package() {
cd "$srcdir/${pkgname}/build"
make install DESTDIR="$pkgdir/"
}
-17
View File
@@ -1,17 +0,0 @@
#!/bin/bash
cd /home/build
mkdir x86_64
cd x86_64
cp ../PKGBUILD .
makepkg
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.pkg.tar.zst \
https://git.tesses.org/api/packages/tesses50/arch/core
cd ..
mkdir powerpc
cd powerpc
cp ../PKGBUILD .
CARCH=powerpc CMAKE_TOOLCHAIN=/opt/cross/ppc/toolchain.cmake makepkg
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.pkg.tar.zst \
https://git.tesses.org/api/packages/tesses50/arch/core
+41
View File
@@ -0,0 +1,41 @@
if [ $# -lt 2 ]
then
echo "Not enough args, pass nfpm arch and debian tripple as argument"
echo "This script requires our docker container: git.tesses.org/tesses50/linux-*:latest"
else
curl https://git.tesses.org/tesses50/tessesframework/releases/download/v$TF_VERSION/tessesframework-v$TF_VERSION-$1.tar.gz | tar xz -C /opt/cross/staging
mkdir -p build
cd build
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib/$2 -DCMAKE_BUILD_TYPE=Release -DCROSSLANG_FETCHCONTENT=OFF -DCROSSLANG_TF_VERSION=$TF_VERSION
make -j`nproc`
make install DESTDIR=debian
cd debian
nfpm package -f ../nfpm.yaml -p deb
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.deb \
https://git.tesses.org/api/packages/tesses50/debian/pool/universal/main/upload
#debian/pool/bionic
cd ..
if [ "$1" = "386" ] || [ "$1" = "arm7" ]
then
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib32
else
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib64
fi
make install DESTDIR=fedora
cd fedora
nfpm package -f ../nfpm.yaml -p rpm
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.rpm \
https://git.tesses.org/api/packages/tesses50/rpm/upload
cd ..
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib
make install DESTDIR=arch
cd arch
nfpm package -f ../nfpm.yaml -p archlinux
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.pkg.tar.zst \
https://git.tesses.org/api/packages/tesses50/arch/core
mkdir -p ../../artifacts
tar czf ../../artifacts/crosslang-$VERSION\-$1\.tar.gz --owner=1000 --group=1000 -C usr/ . -C /opt/cross/staging/ .
fi
+21
View File
@@ -0,0 +1,21 @@
curl https://git.tesses.org/tesses50/tessesframework/releases/download/v$TF_VERSION/tessesframework-v$TF_VERSION-powerpc.tar.gz | tar xz -C /opt/cross/staging
mkdir -p build
pushd build
cmake-cross -S .. -B . -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DCROSSLANG_FETCHCONTENT=OFF -DCROSSLANG_TF_VERSION=$TF_VERSION
make -j`nproc`
mkdir -p /home/build/cl
chown build:build -R /home/build
make install DESTDIR=/home/build/cl/src
cp ppc-pkgbuild /home/build/cl/PKGBUILD
chmod 644 /home/build/cl/PKGBUILD
chown build:build -R /home/build/cl
pushd /home/build/cl
su build -c 'CARCH=powerpc makepkg -d'
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.pkg.tar.zst \
https://git.tesses.org/api/packages/tesses50/arch/core
popd
popd
mkdir -p artifacts
tar czf artifacts/crosslang-$VERSION\-powerpc.tar.gz --owner=1000 --group=1000 -C /home/build/cl/src/usr . -C /opt/cross/staging/ .
+12
View File
@@ -1,5 +1,17 @@
# 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
Fixed Process.ShellFileOrUrl was broken New.ShellFileOrUrl
## 0.0.8
Use new build setup
## 0.0.7
Fix a security vulerability in crossdump that is supposed to use uint32_t but accidently used uint8_t, set to tessesframework=0.0.5
## 0.0.6 ## 0.0.6
Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
+2 -3
View File
@@ -32,8 +32,7 @@ set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/winicon.ico") set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/winicon.ico")
set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MODIFY_PATH ON)
set(CPACK_PACKAGE_VENDOR "Tesses") set(CPACK_PACKAGE_VENDOR "Tesses")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$DESKTOP\\\\CrossLang Interperter.lnk' '$INSTDIR\\\\bin\\\\crossint.exe'") set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$DESKTOP\\\\CrossLang Menu.lnk' '$INSTDIR\\\\bin\\\\crosslang.exe' 'interactive'")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\CrossLang Interperter.lnk' '$INSTDIR\\\\bin\\\\crossint.exe'") set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\CrossLang Menu.lnk' '$INSTDIR\\\\bin\\\\crosslang.exe' 'interactive'")
include(CPack) include(CPack)
+2 -2
View File
@@ -5,10 +5,10 @@ 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 25d67053ccebf209f50e6928fad8827164eb4c28 GIT_TAG 5b54af1728907559999e446e56497055297a3696
) )
set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF) set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF)
FetchContent_MakeAvailable(TessesFramework) FetchContent_MakeAvailable(TessesFramework)
else() else()
find_package(TessesFramework REQUIRED) find_package(TessesFramework REQUIRED)
endif() endif()
+2
View File
@@ -5,3 +5,5 @@ option(CROSSLANG_ENABLE_FFI "Enable libffi" OFF)
option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON) option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON)
option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF) option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF)
option(CROSSLANG_STATIC "Build with static libraries instead of shared" OFF) option(CROSSLANG_STATIC "Build with static libraries instead of shared" OFF)
option(CROSSLANG_NFPM_ARCH "Architecture for NFPM" "")
option(CROSSLANG_TF_VERSION "TessesFramework Version for nfpm and pkgbuild" "")
+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 6) set(CROSSLANG_PATCH_VERSION 10)
+211 -71
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);
@@ -1762,7 +1815,7 @@ class EnvironmentPermissions {
bool canRegisterPath; bool canRegisterPath;
bool canRegisterOGC; bool canRegisterOGC;
bool canRegisterEnv; bool canRegisterEnv;
bool canRegisterClass; bool canRegisterZeClass;
bool sqlite3Scoped; bool sqlite3Scoped;
bool locked; bool locked;
TDictionary *customConsole = nullptr; TDictionary *customConsole = nullptr;
@@ -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);
@@ -1848,7 +1903,7 @@ class TStd {
static void RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment *env); static void RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment *env);
static void RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment *env); static void RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment *env);
static void RegisterProcess(std::shared_ptr<GC> gc, TRootEnvironment *env); static void RegisterProcess(std::shared_ptr<GC> gc, TRootEnvironment *env);
static void RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment *env); static void RegisterZeClass(std::shared_ptr<GC> gc, TRootEnvironment *env);
}; };
class TSubEnvironment : public TEnvironment { class TSubEnvironment : public TEnvironment {
@@ -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);
+183
View File
@@ -0,0 +1,183 @@
# Name. (required)
name: crosslang
# Architecture. (required)
# This will expand any env var you set in the field, e.g. arch: ${GOARCH}
# The architecture is specified using Go nomenclature (GOARCH) and translated
# to the platform specific equivalent. In order to manually set the architecture
# to a platform specific value, set `{format}.arch`.
# Examples: `all`, `amd64`, `386`, `arm5`, `arm6`, `arm7`, `arm64`, `mips`,
# `mipsle`, `mips64le`, `ppc64le`, `s390`, `riscv64`
arch: @CROSSLANG_NFPM_ARCH@
# Platform.
# This will expand any env var you set in the field, e.g. platform: ${GOOS}
# This is only used by the rpm and deb packagers.
# Examples: `linux` (default), `darwin`
platform: linux
# Version. (required)
# This will expand any env var you set in the field, e.g. version: ${SEMVER}
# Some package managers, like deb, require the version to start with a digit.
# Hence, you should not prefix the version with 'v'.
version: @CROSSLANG_MAJOR_VERSION@.@CROSSLANG_MINOR_VERSION@.@CROSSLANG_PATCH_VERSION@
# Version Schema allows you to specify how to parse the version string.
# Default is `semver`
# `semver` attempt to parse the version string as a valid semver version.
# The parser is lenient; it will strip a `v` prefix and will accept
# versions with fewer than 3 components, like `v1.2`.
# If parsing succeeds, then the version will be molded into a format
# compatible with the specific packager used.
# If parsing fails, then the version is used as-is.
# `none` skip trying to parse the version string and just use what is passed in
version_schema: semver
# Version Epoch.
# A package with a higher version epoch will always be considered newer.
# See: https://www.debian.org/doc/debian-policy/ch-controlfields.html#epochs-should-be-used-sparingly
#epoch: 1
# Version Prerelease.
# Default is extracted from `version` if it is semver compatible.
# This is appended to the `version`, e.g. `1.2.3+beta1`. If the `version` is
# semver compatible, then this replaces the prerelease component of the semver.
#prerelease: alpha
# Version Metadata (previously deb.metadata).
# Default is extracted from `version` if it is semver compatible.
# Setting metadata might interfere with version comparisons depending on the
# packager. If the `version` is semver compatible, then this replaces the
# version metadata component of the semver.
# version_metadata: git
# Version Release, aka revision.
# This will expand any env var you set in the field, e.g. release: ${VERSION_RELEASE}
# This is appended to the `version` after `prerelease`. This should be
# incremented if you release an updated package of the same upstream version,
# and it should reset to 1 when bumping the version.
release: 1
# Section.
# This is only used by the deb packager.
# See: https://www.debian.org/doc/debian-policy/ch-archive.html#sections
section: default
# Priority.
# Defaults to `optional` on deb
# Defaults to empty on rpm and apk
# See: https://www.debian.org/doc/debian-policy/ch-archive.html#priorities
priority: extra
# Maintainer. (required)
# This will expand any env var you set in the field, e.g. maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
# Defaults to empty on rpm and apk
# Leaving the 'maintainer' field unset will not be allowed in a future version
maintainer: Mike Nolan <tesses@tesses.net>
# Description.
# This will expand any env var you set in the field, e.g. description: ${DESCRIPTION}
# Defaults to `no description given`.
# Most packagers call for a one-line synopsis of the package. Some (like deb)
# also call for a multi-line description starting on the second line.
description: TessesFramework a library to make C++ easier for me, used in CrossLang
# Vendor.
# This will expand any env var you set in the field, e.g. vendor: ${VENDOR}
# This is only used by the rpm packager.
vendor: Tesses
# Package's homepage.
# This will expand any env var you set in the field, e.g. homepage: ${CI_PROJECT_URL}
homepage: https://git.tesses.org/tesses50/crosslang
# License.
license: GPLv3
# Date to be used as mtime on internal files.
#
# Default is the value of $SOURCE_DATE_EPOCH (which should be an Unix time),
# or the current time.
# Read more about SOURCE_DATE_EPOCH at https://reproducible-builds.org/docs/source-date-epoch/
#mtime: "2009-11-10T23:00:00Z"
# Changelog YAML file, see: https://github.com/goreleaser/chglog
# changelog: "changelog.yaml"
# Disables globbing for files, config_files, etc.
# disable_globbing: false
# Packages it replaces. (overridable)
# This will expand any env var you set in the field, e.g. ${REPLACE_BLA}
# the env var approach can be used to account for differences in platforms
#replaces:
# - foobar
# - ${REPLACE_BLA}
# Packages it provides. (overridable)
# This will expand any env var you set in the field, e.g. ${PROVIDES_BLA}
# the env var approach can be used to account for differences in platforms
#provides:
# - bar
# - ${PROVIDES_BLA}
# Dependencies. (overridable)
# This will expand any env var you set in the field, e.g. ${DEPENDS_NGINX}
# the env var approach can be used to account for differences in platforms
# e.g. rhel needs nginx >= 1:1.18 and deb needs nginx (>= 1.18.0)
#depends:
# - git
# - ${DEPENDS_NGINX}
# Recommended packages. (overridable)
# This will expand any env var you set in the field, e.g. ${RECOMMENDS_BLA}
# the env var approach can be used to account for differences in platforms
#recommends:
# - golang
# - ${RECOMMENDS_BLA}
# Suggested packages. (overridable)
# This will expand any env var you set in the field, e.g. ${SUGGESTS_BLA}
# the env var approach can be used to account for differences in platforms
#suggests:
# - bzr
# Packages it conflicts with. (overridable)
# This will expand any env var you set in the field, e.g. ${CONFLICTS_BLA}
# the env var approach can be used to account for differences in platforms
#conflicts:
# - mercurial
# - ${CONFLICTS_BLA}
# Contents to add to the package
# This can be binaries or any other files.
contents:
- src: usr/
dst: /usr/
type: tree
# Umask to be used on files without explicit mode set.
#
# By default, nFPM will inherit the mode of the original file that's being
# added.
# This may lead to issues if these files are checkout out in Git, for example,
# as it won't keep all the permissions on fresh checkouts, or if the local
# system has a problematic umask setting.
#
# This setting allows to set the umask for all files that are added to the
# package without a specific file_info.mode set.
#
# Default: 0o002 (will remove world-writable permissions)
umask: 0o002
overrides:
deb:
depends:
- "tessesframework (= @CROSSLANG_TF_VERSION@-1)"
rpm:
depends:
- "tessesframework = @CROSSLANG_TF_VERSION@-1"
archlinux:
depends:
- "tessesframework=@CROSSLANG_TF_VERSION@-1"
+21
View File
@@ -0,0 +1,21 @@
# Maintainer: Mike Nolan <tesses@tesses.net>
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
pkgver=@CROSSLANG_MAJOR_VERSION@.@CROSSLANG_MINOR_VERSION@.@CROSSLANG_PATCH_VERSION@
pkgrel=1
pkgdesc=""
arch=('powerpc')
url="https://git.tesses.org/tesses50/crosslang"
license=('GPLv3')
groups=()
depends=('tessesframework=@CROSSLANG_TF_VERSION@-1')
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
install=
source=()
noextract=()
sha256sums=()
options=(!buildflags !strip)
package() {
cp -r "${srcdir}/"* "${pkgdir}/"
}
+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 {
+1 -1
View File
@@ -94,7 +94,7 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
uint32_t ents = EnsureInt(strm); uint32_t ents = EnsureInt(strm);
for (uint8_t k = 0; k < ents; k++) { for (uint32_t k = 0; k < ents; k++) {
Ensure(strm, main_header, 1); Ensure(strm, main_header, 1);
uint8_t flags = main_header[0]; uint8_t flags = main_header[0];
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/" std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/"
+7 -7
View File
@@ -85,7 +85,7 @@ TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
"Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm"; "Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm";
if (argv.size() == 2 && argv[1] == "configdir") { if (argv.size() == 2 && argv[1] == "configdir") {
std::cout << dir.ToString() << std::endl; std::cout << dir.ToString() << std::endl;
return 0; return (int64_t)0;
} }
if (argv.size() > 1 && argv[1] == "update-shell") { if (argv.size() > 1 && argv[1] == "update-shell") {
@@ -101,15 +101,15 @@ TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
auto strm = resp.ReadAsStream(); auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, subdir); CrossLang::CrossArchiveExtract(strm, subdir);
return 0; return (int64_t)0;
} else { } else {
std::cout << "Error when fetching the script error: " std::cout << "Error when fetching the script error: "
<< std::to_string(resp.statusCode) << " " << std::to_string(resp.statusCode) << " "
<< HttpUtils::StatusCodeString(resp.statusCode) << HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl; << std::endl;
return 1; return (int64_t)1;
} }
return 0; return (int64_t)0;
} }
if (!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) { if (!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) {
@@ -125,12 +125,12 @@ TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
CrossLang::CrossArchiveExtract(strm, subdir); CrossLang::CrossArchiveExtract(strm, subdir);
} else { } else {
return 1; return (int64_t)1;
} }
} else { } else {
if (!Download(filename, subdir)) if (!Download(filename, subdir))
return 1; return (int64_t)1;
return 0; return (int64_t)0;
} }
} }
+8 -8
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") {
@@ -192,7 +192,7 @@ void CrossLangCompiler(std::vector<std::string> &argv) {
if (comptime == "secure") { if (comptime == "secure") {
TStd::RegisterConsole(gc, env); TStd::RegisterConsole(gc, env);
TStd::RegisterClass(gc, env); TStd::RegisterZeClass(gc, env);
TStd::RegisterCrypto(gc, env); TStd::RegisterCrypto(gc, env);
TStd::RegisterDictionary(gc, env); TStd::RegisterDictionary(gc, env);
TStd::RegisterJson(gc, env); TStd::RegisterJson(gc, env);
@@ -201,7 +201,7 @@ void CrossLangCompiler(std::vector<std::string> &argv) {
env->permissions.locked = true; env->permissions.locked = true;
} else if (comptime == "secure_file") { } else if (comptime == "secure_file") {
TStd::RegisterConsole(gc, env); TStd::RegisterConsole(gc, env);
TStd::RegisterClass(gc, env); TStd::RegisterZeClass(gc, env);
TStd::RegisterCrypto(gc, env); TStd::RegisterCrypto(gc, env);
TStd::RegisterDictionary(gc, env); TStd::RegisterDictionary(gc, env);
TStd::RegisterJson(gc, env); TStd::RegisterJson(gc, env);
+3 -3
View File
@@ -7,7 +7,7 @@ TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
std::cout << "USAGE: " std::cout << "USAGE: "
<< (argv.empty() ? (std::string) "crossvm" : argv[0]) << (argv.empty() ? (std::string) "crossvm" : argv[0])
<< " <filename.crvm> <args...>" << std::endl; << " <filename.crvm> <args...>" << std::endl;
return 1; return (int64_t)1;
} }
env->LoadFileWithDependencies( env->LoadFileWithDependencies(
@@ -33,7 +33,7 @@ TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2}); auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(), res); auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(), res);
if (svr2 == nullptr) if (svr2 == nullptr)
return 1; return (int64_t)1;
Tesses::Framework::Http::HttpServer svr(port, svr2); Tesses::Framework::Http::HttpServer svr(port, svr2);
svr.StartAccepting(); svr.StartAccepting();
TF_RunEventLoop(); TF_RunEventLoop();
@@ -46,7 +46,7 @@ TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
_co->CallMethod(ls, "", "Close", {}); _co->CallMethod(ls, "", "Close", {});
} }
TF_Quit(); TF_Quit();
return 0; return (int64_t)0;
} else { } else {
TList *args = TList::Create(ls); TList *args = TList::Create(ls);
for (size_t arg = 1; arg < argv.size(); arg++) for (size_t arg = 1; arg < argv.size(); arg++)
+2 -2
View File
@@ -190,9 +190,9 @@ static TObject Class_GetInfo(TRootEnvironment *env, GCList &ls,
return nullptr; return nullptr;
} }
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment *env) { void TStd::RegisterZeClass(std::shared_ptr<GC> gc, TRootEnvironment *env) {
GCList ls(gc); GCList ls(gc);
env->permissions.canRegisterClass = true; env->permissions.canRegisterZeClass = true;
TDictionary *cls = env->EnsureDictionary(gc, "Class"); TDictionary *cls = env->EnsureDictionary(gc, "Class");
gc->BarrierBegin(); gc->BarrierBegin();
+18 -5
View File
@@ -3,7 +3,17 @@
#include <iostream> #include <iostream>
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TObject Console_setInvertedColors(GCList &ls, std::vector<TObject> args) {
bool inverted;
if (GetArgument(args, 0, inverted)) {
Tesses::Framework::Console::SetInvertedColors(inverted);
}
return Undefined();
}
TObject Console_Reset(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Console::Reset();
return Undefined();
}
TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) { TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::IsTTY(); return Tesses::Framework::Console::IsTTY();
@@ -62,18 +72,21 @@ 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) {
if (args.size() < 1) { if (args.size() < 1) {
Tesses::Framework::Console::WriteLineView(""); Tesses::Framework::Console::WriteLineView("");
return Undefined(); return Undefined();
} }
Tesses::Framework::Console::WriteLine(ToString(ls.GetGC(), args[0])); std::string text = ToString(ls.GetGC(), args[0]);
Tesses::Framework::Console::WriteLine(text);
return Undefined(); return Undefined();
} }
@@ -143,7 +156,7 @@ TObject Console_List(GCList &ls, std::vector<TObject> args) {
return (int64_t)Tesses::Framework::Console::List(items); return (int64_t)Tesses::Framework::Console::List(items);
} }
return 0; return (int64_t)0;
} }
void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) { void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterConsole = true; env->permissions.canRegisterConsole = true;
-4
View File
@@ -1,10 +1,6 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
#include "TessesFramework/Serialization/BitConverter.hpp" #include "TessesFramework/Serialization/BitConverter.hpp"
#if defined(_WIN32)
#include <windows.h>
#endif
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
using namespace Tesses::Framework::Platform::Environment; using namespace Tesses::Framework::Platform::Environment;
#if defined(_WIN32) #if defined(_WIN32)
+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) {
+62 -21
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) {
@@ -215,7 +255,7 @@ class TServerContext : public TNativeObjectThatReturnsHttpDictionary {
else if (key == "getIP") else if (key == "getIP")
return ctx->ip; return ctx->ip;
else if (key == "getPort") else if (key == "getPort")
return ctx->port; return (int64_t)ctx->port;
else if (key == "getOriginalPath") else if (key == "getOriginalPath")
return ctx->originalPath; return ctx->originalPath;
else if (key == "getPath") else if (key == "getPath")
@@ -235,10 +275,13 @@ class TServerContext : public TNativeObjectThatReturnsHttpDictionary {
return sc; return sc;
} }
} else if (key == "getStatusCode") } else if (key == "getStatusCode")
return ctx->statusCode; return (int64_t)ctx->statusCode;
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);
@@ -780,18 +823,20 @@ static TObject Net_Http_ListenOnUnusedPort(GCList &ls,
static TObject Net_Http_MimeType(GCList &ls, std::vector<TObject> args) { 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();
return HttpUtils::MimeType(p2); return HttpUtils::GetMimeTypePath(p);
} }
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)",
+11 -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");
@@ -280,6 +276,16 @@ void TStd::RegisterProcess(std::shared_ptr<GC> gc, TRootEnvironment *env) {
} }
return Undefined(); return Undefined();
}); });
dict->DeclareFunction(
gc, "ShellFileOrUrl", "Launch file or url in shell", {"urlOrFilename"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
std::string fileOrUrl;
if (GetArgument(args, 0, fileOrUrl))
Tesses::Framework::Platform::ShellFileOrUrl(fileOrUrl);
return Undefined();
});
gc->BarrierEnd(); gc->BarrierEnd();
} }
} // namespace Tesses::CrossLang } // namespace Tesses::CrossLang
+21 -25
View File
@@ -6,28 +6,17 @@
#include <memory> #include <memory>
#include <variant> #include <variant>
#include <vector> #include <vector>
#if !defined(CROSSLANG_STATIC) #if !defined(CROSSLANG_STATIC)
#if defined(CROSSLANG_ENABLE_FFI) #if defined(CROSSLANG_ENABLE_FFI)
#include <ffi.h> #include <ffi.h>
#endif #endif
#if defined(_WIN32) #if !defined(_WIN32)
#include <windows.h>
#include <time.h>
#undef min
#undef max
#else
#include <dlfcn.h> #include <dlfcn.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
#else #else
#if defined(_WIN32) #if !defined(_WIN32)
#include <windows.h>
#include <time.h>
#undef min
#undef max
#else
#include <unistd.h> #include <unistd.h>
#endif #endif
#endif #endif
@@ -70,15 +59,18 @@ class DL {
Tesses::Framework::Filesystem::LocalFilesystem lfs; Tesses::Framework::Filesystem::LocalFilesystem lfs;
std::string str = lfs.VFSPathToSystem(p); std::string str = lfs.VFSPathToSystem(p);
#if defined(_WIN32) #if defined(_WIN32)
handle =
LoadLibraryExA(str.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); throw std::runtime_error("I removed support on this platform");
// handle =LoadLibraryExA(str.c_str(), NULL,
// LOAD_WITH_ALTERED_SEARCH_PATH);
#else #else
handle = dlopen(str.c_str(), RTLD_LAZY); handle = dlopen(str.c_str(), RTLD_LAZY);
#endif #endif
} }
template <typename T> T Resolve(std::string name) { template <typename T> T Resolve(std::string name) {
#if defined(_WIN32) #if defined(_WIN32)
return (T)GetProcAddress((HMODULE)handle, name.c_str()); throw std::runtime_error("I removed support on this platform");
// return (T)GetProcAddress((HMODULE)handle, name.c_str());
#else #else
return (T)dlsym(handle, name.c_str()); return (T)dlsym(handle, name.c_str());
@@ -86,7 +78,9 @@ class DL {
} }
~DL() { ~DL() {
#if defined(_WIN32) #if defined(_WIN32)
FreeLibrary((HMODULE)handle);
throw std::runtime_error("I removed support on this platform");
// FreeLibrary((HMODULE)handle);
#else #else
dlclose(handle); dlclose(handle);
#endif #endif
@@ -1004,11 +998,7 @@ static TObject YieldEnumerableFunc(GCList &ls, std::vector<TObject> args) {
static TObject DateTime_Sleep(GCList &ls, std::vector<TObject> args) { static TObject DateTime_Sleep(GCList &ls, std::vector<TObject> args) {
int64_t msec; int64_t msec;
if (GetArgument(args, 0, msec)) { if (GetArgument(args, 0, msec)) {
#if defined(_WIN32) Tesses::Framework::TF_Sleep(msec);
Sleep((int)msec);
#else
usleep(1000 * msec);
#endif
} }
return nullptr; return nullptr;
} }
@@ -1587,7 +1577,7 @@ void TStd::RegisterStd(
RegisterCrypto(gc, env); RegisterCrypto(gc, env);
RegisterOGC(gc, env); RegisterOGC(gc, env);
RegisterProcess(gc, env); RegisterProcess(gc, env);
RegisterClass(gc, env); RegisterZeClass(gc, env);
gc->RegisterEverything(env); gc->RegisterEverything(env);
@@ -1613,7 +1603,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() {
+6 -2
View File
@@ -16,8 +16,12 @@ TObject TRandom::CallMethod(GCList &ls, std::string name,
return (int64_t)random.Next((uint32_t)first); return (int64_t)random.Next((uint32_t)first);
} }
{
return random.Next(); uint64_t num = random.Next();
int64_t val2 = 0;
memcpy(&val2, &num, sizeof(int64_t));
return val2;
}
} }
if (name == "NextByte") { if (name == "NextByte") {
+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() {
+6 -6
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));
} }
@@ -2292,9 +2292,9 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
} }
if (key == "RegisterClass") { if (key == "RegisterClass") {
if ((myEnv->permissions.canRegisterEverything || if ((myEnv->permissions.canRegisterEverything ||
myEnv->permissions.canRegisterClass) && myEnv->permissions.canRegisterZeClass) &&
!rootEnv->permissions.locked) !rootEnv->permissions.locked)
TStd::RegisterClass(gc, rootEnv); TStd::RegisterZeClass(gc, rootEnv);
cse.back()->Push(gc, nullptr); cse.back()->Push(gc, nullptr);
return false; return false;
} }
@@ -3195,7 +3195,7 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
if (GetArgument(args, 0, index) && if (GetArgument(args, 0, index) &&
(size_t)index < bArray->data.size() && (size_t)index < bArray->data.size() &&
(size_t)index + 8 <= bArray->data.size()) { (size_t)index + 8 <= bArray->data.size()) {
uint64_t value = BitConverter::ToDoubleLE( double value = BitConverter::ToDoubleLE(
bArray->data[(size_t)index]); bArray->data[(size_t)index]);
cse.back()->Push(gc, value); cse.back()->Push(gc, value);
@@ -3218,7 +3218,7 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
if (GetArgument(args, 0, index) && if (GetArgument(args, 0, index) &&
(size_t)index < bArray->data.size() && (size_t)index < bArray->data.size() &&
(size_t)index + 8 <= bArray->data.size()) { (size_t)index + 8 <= bArray->data.size()) {
uint64_t value = BitConverter::ToDoubleBE( double value = BitConverter::ToDoubleBE(
bArray->data[(size_t)index]); bArray->data[(size_t)index]);
cse.back()->Push(gc, value); cse.back()->Push(gc, value);
+1 -1
View File
@@ -188,7 +188,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
if (netStrm != nullptr) { if (netStrm != nullptr) {
if (key == "Port") { if (key == "Port") {
cse.back()->Push(gc, netStrm->GetPort()); cse.back()->Push(gc, (int64_t)netStrm->GetPort());
return false; return false;
} }
} }
+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 -82
View File
@@ -2,16 +2,25 @@
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include <time.h> #include <time.h>
#if defined(_WIN32) #if !defined(_WIN32)
#include <windows.h>
#else
#include <unistd.h> #include <unistd.h>
#endif #endif
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 +83,13 @@ 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;
#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 +108,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 +161,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 +201,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();