First commit to big refactor
This commit is contained in:
@@ -84,31 +84,33 @@ class TVMVersion {
|
|||||||
*
|
*
|
||||||
* @return uint8_t The major
|
* @return uint8_t The major
|
||||||
*/
|
*/
|
||||||
uint8_t Major() { return major; }
|
uint8_t Major() const { return major; }
|
||||||
/**
|
/**
|
||||||
* @brief Minor
|
* @brief Minor
|
||||||
*
|
*
|
||||||
* @return uint8_t The minor
|
* @return uint8_t The minor
|
||||||
*/
|
*/
|
||||||
uint8_t Minor() { return minor; }
|
uint8_t Minor() const { return minor; }
|
||||||
/**
|
/**
|
||||||
* @brief Patch
|
* @brief Patch
|
||||||
*
|
*
|
||||||
* @return uint8_t The patch
|
* @return uint8_t The patch
|
||||||
*/
|
*/
|
||||||
uint8_t Patch() { return patch; }
|
uint8_t Patch() const { return patch; }
|
||||||
/**
|
/**
|
||||||
* @brief Build
|
* @brief Build
|
||||||
*
|
*
|
||||||
* @return uint16_t The build
|
* @return uint16_t The build
|
||||||
*/
|
*/
|
||||||
uint16_t Build() { return build >> 2; }
|
uint16_t Build() const { return build >> 2; }
|
||||||
/**
|
/**
|
||||||
* @brief Stage (dev, alpha, beta or prod)
|
* @brief Stage (dev, alpha, beta or prod)
|
||||||
*
|
*
|
||||||
* @return TVMVersionStage The stage
|
* @return TVMVersionStage The stage
|
||||||
*/
|
*/
|
||||||
TVMVersionStage VersionStage() { return (TVMVersionStage)(build & 3); }
|
TVMVersionStage VersionStage() const {
|
||||||
|
return static_cast<TVMVersionStage>(build & 3);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Set the Major
|
* @brief Set the Major
|
||||||
*
|
*
|
||||||
@@ -215,7 +217,7 @@ class TVMVersion {
|
|||||||
*
|
*
|
||||||
* @param versionData an array that is 5 bytes long
|
* @param versionData an array that is 5 bytes long
|
||||||
*/
|
*/
|
||||||
void ToArray(uint8_t *versionData) {
|
void ToArray(uint8_t *versionData) const {
|
||||||
versionData[0] = major;
|
versionData[0] = major;
|
||||||
versionData[1] = minor;
|
versionData[1] = minor;
|
||||||
versionData[2] = patch;
|
versionData[2] = patch;
|
||||||
@@ -267,7 +269,7 @@ class TVMVersion {
|
|||||||
* @return int returns 1 if this is newer than other version, 0 if same, -1
|
* @return int returns 1 if this is newer than other version, 0 if same, -1
|
||||||
* if this is older than other version
|
* if this is older than other version
|
||||||
*/
|
*/
|
||||||
int CompareTo(TVMVersion &version) {
|
int CompareTo(const TVMVersion &version) const {
|
||||||
if (this->major > version.major)
|
if (this->major > version.major)
|
||||||
return 1;
|
return 1;
|
||||||
if (this->major < version.major)
|
if (this->major < version.major)
|
||||||
@@ -291,7 +293,7 @@ class TVMVersion {
|
|||||||
*
|
*
|
||||||
* @return uint64_t serialized as a long
|
* @return uint64_t serialized as a long
|
||||||
*/
|
*/
|
||||||
uint64_t AsLong() {
|
uint64_t AsLong() const {
|
||||||
uint64_t v = (uint64_t)major << 32;
|
uint64_t v = (uint64_t)major << 32;
|
||||||
v |= (uint64_t)minor << 24;
|
v |= (uint64_t)minor << 24;
|
||||||
v |= (uint64_t)patch << 16;
|
v |= (uint64_t)patch << 16;
|
||||||
@@ -304,7 +306,7 @@ class TVMVersion {
|
|||||||
* @return int CompareTo(RuntimeVersion) where RuntimeVersion is the runtime
|
* @return int CompareTo(RuntimeVersion) where RuntimeVersion is the runtime
|
||||||
* version
|
* version
|
||||||
*/
|
*/
|
||||||
int CompareToRuntime() {
|
int CompareToRuntime() const {
|
||||||
TVMVersion version(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
TVMVersion version(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||||
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||||
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||||
@@ -319,9 +321,10 @@ class TVMVersion {
|
|||||||
* @return true the parsing succeeded
|
* @return true the parsing succeeded
|
||||||
* @return false the parsing failed
|
* @return false the parsing failed
|
||||||
*/
|
*/
|
||||||
static bool TryParse(std::string versionStr, TVMVersion &version) {
|
static bool TryParse(const std::string &versionStr, TVMVersion &version) {
|
||||||
if (versionStr.empty())
|
if (versionStr.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t sep = versionStr.find_last_of('-');
|
size_t sep = versionStr.find_last_of('-');
|
||||||
|
|
||||||
std::string left = versionStr;
|
std::string left = versionStr;
|
||||||
@@ -399,7 +402,7 @@ class TVMVersion {
|
|||||||
* @return std::string the version string like 1.0.0.0-prod (or dev, alpha,
|
* @return std::string the version string like 1.0.0.0-prod (or dev, alpha,
|
||||||
* beta)
|
* beta)
|
||||||
*/
|
*/
|
||||||
std::string ToString() {
|
std::string ToString() const {
|
||||||
std::string str = {};
|
std::string str = {};
|
||||||
str.append(std::to_string((int)this->Major()));
|
str.append(std::to_string((int)this->Major()));
|
||||||
str.push_back('.');
|
str.push_back('.');
|
||||||
@@ -408,14 +411,20 @@ class TVMVersion {
|
|||||||
str.append(std::to_string((int)this->Patch()));
|
str.append(std::to_string((int)this->Patch()));
|
||||||
str.push_back('.');
|
str.push_back('.');
|
||||||
str.append(std::to_string((int)this->Build()));
|
str.append(std::to_string((int)this->Build()));
|
||||||
if (this->VersionStage() == TVMVersionStage::DevVersion) {
|
|
||||||
|
switch (this->VersionStage()) {
|
||||||
|
case TVMVersionStage::DevVersion:
|
||||||
str.append("-dev");
|
str.append("-dev");
|
||||||
} else if (this->VersionStage() == TVMVersionStage::AlphaVersion) {
|
break;
|
||||||
|
case TVMVersionStage::AlphaVersion:
|
||||||
str.append("-alpha");
|
str.append("-alpha");
|
||||||
} else if (this->VersionStage() == TVMVersionStage::BetaVersion) {
|
break;
|
||||||
|
case TVMVersionStage::BetaVersion:
|
||||||
str.append("-beta");
|
str.append("-beta");
|
||||||
} else if (this->VersionStage() == TVMVersionStage::ProductionVersion) {
|
break;
|
||||||
|
case TVMVersionStage::ProductionVersion:
|
||||||
str.append("-prod");
|
str.append("-prod");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -1347,14 +1356,67 @@ class Parser {
|
|||||||
class THeapObject;
|
class THeapObject;
|
||||||
class CallStackEntry;
|
class CallStackEntry;
|
||||||
class InterperterThread;
|
class InterperterThread;
|
||||||
|
class TString;
|
||||||
class THeapObject {
|
class THeapObject {
|
||||||
|
protected:
|
||||||
|
virtual bool opAdd(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opSub(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opTimes(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opDiv(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opMod(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opLessThan(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opGreaterThan(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opLessThanEqual(InterperterThread *thrd,
|
||||||
|
std::shared_ptr<GC> gc, TObject rhs);
|
||||||
|
virtual bool opGreaterThanEqual(InterperterThread *thrd,
|
||||||
|
std::shared_ptr<GC> gc, TObject rhs);
|
||||||
|
virtual bool opLeftShift(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opRightShift(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opBitwiseOr(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opBitwiseAnd(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opXor(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
virtual bool opNeg(InterperterThread *thrd, std::shared_ptr<GC> gc);
|
||||||
|
virtual bool opBitwiseNot(InterperterThread *thrd, std::shared_ptr<GC> gc);
|
||||||
|
virtual bool opLogicalNot(InterperterThread *thrd, std::shared_ptr<GC> gc);
|
||||||
|
virtual bool opExecuteMethod(InterperterThread *thrd,
|
||||||
|
std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args);
|
||||||
|
virtual bool opSetField(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name, TObject value);
|
||||||
|
virtual bool opGetField(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool marked;
|
bool marked;
|
||||||
virtual void Mark() { marked = true; }
|
virtual void Mark() { marked = true; }
|
||||||
THeapObject() = default;
|
THeapObject() = default;
|
||||||
THeapObject(const THeapObject &) = delete;
|
THeapObject(const THeapObject &) = delete;
|
||||||
THeapObject &operator=(const THeapObject &) = delete;
|
THeapObject &operator=(const THeapObject &) = delete;
|
||||||
|
|
||||||
virtual ~THeapObject() = default;
|
virtual ~THeapObject() = default;
|
||||||
|
|
||||||
|
virtual std::string TypeName() = 0;
|
||||||
|
|
||||||
|
virtual TString *ToString(GCList &ls);
|
||||||
|
virtual bool ToBool();
|
||||||
|
|
||||||
|
virtual bool IsEqualTo(std::shared_ptr<GC> gc, TObject rhs);
|
||||||
|
virtual bool IsNotEqualTo(std::shared_ptr<GC> gc, TObject rhs);
|
||||||
|
|
||||||
|
friend class InterperterThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this is a dummy type with
|
// this is a dummy type with
|
||||||
@@ -1368,13 +1430,12 @@ class TContinue {};
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using TObject =
|
using TObject =
|
||||||
std::variant<Undefined, int64_t, double, char, bool, std::string,
|
std::variant<Undefined, int64_t, double, char, bool, std::regex,
|
||||||
std::regex, Tesses::Framework::Filesystem::VFSPath,
|
Tesses::Framework::Filesystem::VFSPath, MethodInvoker,
|
||||||
MethodInvoker, THeapObject *, TVMVersion,
|
THeapObject *, 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::Filesystem::VFS>,
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS>,
|
|
||||||
std::shared_ptr<Tesses::Framework::Http::IHttpServer>,
|
std::shared_ptr<Tesses::Framework::Http::IHttpServer>,
|
||||||
std::shared_ptr<Tesses::Framework::Http::HttpRequestBody>,
|
std::shared_ptr<Tesses::Framework::Http::HttpRequestBody>,
|
||||||
std::shared_ptr<Tesses::Framework::TextStreams::TextReader>,
|
std::shared_ptr<Tesses::Framework::TextStreams::TextReader>,
|
||||||
@@ -1432,7 +1493,7 @@ class GC : public std::enable_shared_from_this<GC> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string GetObjectTypeString(TObject obj);
|
std::string GetObjectTypeString(TObject obj);
|
||||||
std::string ToString(std::shared_ptr<GC> gc, TObject obj);
|
std::string ObjectToString(std::shared_ptr<GC> gc, TObject obj);
|
||||||
|
|
||||||
class GCList {
|
class GCList {
|
||||||
std::vector<THeapObject *> items;
|
std::vector<THeapObject *> items;
|
||||||
@@ -1452,6 +1513,8 @@ class GCList {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TString *FromString(std::string_view str);
|
||||||
|
|
||||||
void Add(TObject v);
|
void Add(TObject v);
|
||||||
void Remove(TObject v);
|
void Remove(TObject v);
|
||||||
void Mark();
|
void Mark();
|
||||||
@@ -1470,36 +1533,164 @@ class TFileChunk : public THeapObject {
|
|||||||
static TFileChunk *Create(GCList &gc);
|
static TFileChunk *Create(GCList &gc);
|
||||||
TFile *file;
|
TFile *file;
|
||||||
std::vector<uint8_t> code;
|
std::vector<uint8_t> code;
|
||||||
std::vector<std::string> args;
|
std::vector<TString *> args;
|
||||||
std::optional<std::string> name;
|
std::optional<TString *> name;
|
||||||
|
void Mark();
|
||||||
|
};
|
||||||
|
class TMutByteView;
|
||||||
|
class TByteView : public THeapObject {
|
||||||
|
public:
|
||||||
|
virtual std::pair<const uint8_t *, size_t> GetBounds() const = 0;
|
||||||
|
TString *ToString(GCList &ls);
|
||||||
|
void CopyTo(TMutByteView *view);
|
||||||
|
void CopyTo(TMutByteView *view, size_t srcOffset, size_t destOffset,
|
||||||
|
size_t length);
|
||||||
|
std::pair<const uint8_t *, size_t>
|
||||||
|
GetBoundsConstrained(size_t offset = 0, size_t length = (size_t)-1) {
|
||||||
|
auto bounds = GetBounds();
|
||||||
|
|
||||||
|
if (bounds.first == nullptr || offset >= bounds.second || length == 0)
|
||||||
|
return std::pair<const uint8_t *, size_t>(nullptr, 0);
|
||||||
|
|
||||||
|
length = std::min(length, bounds.second - offset);
|
||||||
|
|
||||||
|
return std::pair<const uint8_t *, size_t>(bounds.first + offset,
|
||||||
|
length);
|
||||||
|
}
|
||||||
|
std::string TypeName();
|
||||||
|
bool opExecuteMethod(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args);
|
||||||
|
bool opGetField(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name);
|
||||||
|
|
||||||
|
int64_t GetAt(size_t index) {
|
||||||
|
auto res = GetBoundsConstrained(index, 1);
|
||||||
|
if (res.first == nullptr || res.second != 1)
|
||||||
|
return -1;
|
||||||
|
return *res.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TMutByteView : public TByteView {
|
||||||
|
public:
|
||||||
|
std::pair<const uint8_t *, size_t> GetBounds() const;
|
||||||
|
virtual std::pair<uint8_t *, size_t> GetMutableBounds() = 0;
|
||||||
|
std::pair<uint8_t *, size_t>
|
||||||
|
GetMutableBoundsConstrained(size_t offset = 0, size_t length = (size_t)-1) {
|
||||||
|
auto bounds = GetMutableBounds();
|
||||||
|
if (bounds.first == nullptr || offset >= bounds.second || length == 0)
|
||||||
|
return std::pair<uint8_t *, size_t>(nullptr, 0);
|
||||||
|
|
||||||
|
length = std::min(length, bounds.second - offset);
|
||||||
|
|
||||||
|
return std::pair<uint8_t *, size_t>(bounds.first + offset, length);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TMemoryStreamMutByteView : public TMutByteView {
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::MemoryStream> strm;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TMemoryStreamMutByteView(
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::MemoryStream> strm);
|
||||||
|
std::pair<uint8_t *, size_t> GetMutableBounds();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TString : public TByteView {
|
||||||
|
private:
|
||||||
|
std::string text;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool opAdd(InterperterThread *thrd, std::shared_ptr<GC> gc, TObject rhs);
|
||||||
|
bool opLessThan(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
bool opGreaterThan(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
bool opLessThanEqual(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
bool opGreaterThanEqual(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs);
|
||||||
|
|
||||||
|
public:
|
||||||
|
TString();
|
||||||
|
explicit TString(std::string_view str);
|
||||||
|
TString(std::string_view lhs, std::string_view rhs);
|
||||||
|
TString(const char *text, size_t len);
|
||||||
|
template <typename Itterator>
|
||||||
|
TString(Itterator begin, Itterator end) : text(begin, end) {}
|
||||||
|
TString(std::string &&str);
|
||||||
|
|
||||||
|
const std::string &GetString() const;
|
||||||
|
|
||||||
|
std::pair<const uint8_t *, size_t> GetBounds() const;
|
||||||
|
|
||||||
|
TString *ToString(GCList &ls);
|
||||||
|
|
||||||
|
std::string TypeName();
|
||||||
|
|
||||||
|
bool IsEqualTo(std::shared_ptr<GC> gc, TObject rhs);
|
||||||
|
bool IsNotEqualTo(std::shared_ptr<GC> gc, TObject rhs);
|
||||||
|
};
|
||||||
|
class TResource : public TByteView {
|
||||||
|
std::vector<uint8_t> bytes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TResource(std::vector<uint8_t> &&bytes);
|
||||||
|
|
||||||
|
std::pair<const uint8_t *, size_t> GetBounds() const;
|
||||||
|
std::string TypeName();
|
||||||
|
};
|
||||||
|
class TByteArray : public TMutByteView {
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TByteArray(size_t length);
|
||||||
|
TByteArray(TByteView *view);
|
||||||
|
void Resize(size_t length);
|
||||||
|
std::pair<uint8_t *, size_t> GetMutableBounds();
|
||||||
|
std::string TypeName();
|
||||||
|
};
|
||||||
|
class TMutSpan : public TMutByteView {
|
||||||
|
TMutByteView *view;
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TMutSpan(TMutByteView *view, int64_t offset, int64_t length);
|
||||||
|
std::pair<uint8_t *, size_t> GetMutableBounds();
|
||||||
|
std::string TypeName();
|
||||||
|
void Mark();
|
||||||
|
};
|
||||||
|
class TSpan : public TByteView {
|
||||||
|
TByteView *view;
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TSpan(TByteView *view, int64_t offset, int64_t length);
|
||||||
|
std::pair<const uint8_t *, size_t> GetBounds() const;
|
||||||
|
std::string TypeName();
|
||||||
void Mark();
|
void Mark();
|
||||||
};
|
};
|
||||||
|
|
||||||
class TByteArray : public THeapObject {
|
|
||||||
public:
|
|
||||||
std::vector<uint8_t> data;
|
|
||||||
[[deprecated("Use GCList::Create<T>() instead")]]
|
|
||||||
static TByteArray *Create(GCList *gc);
|
|
||||||
[[deprecated("Use GCList::Create<T>() instead")]]
|
|
||||||
static TByteArray *Create(GCList &gc);
|
|
||||||
};
|
|
||||||
enum class TClassModifier { Private, Protected, Public, Static };
|
enum class TClassModifier { Private, Protected, Public, Static };
|
||||||
class TClassEntry {
|
class TClassEntry {
|
||||||
public:
|
public:
|
||||||
TClassModifier modifier;
|
TClassModifier modifier;
|
||||||
bool isFunction;
|
bool isFunction;
|
||||||
bool isAbstract;
|
bool isAbstract;
|
||||||
std::vector<std::string> args;
|
std::vector<TString *> args;
|
||||||
std::string documentation;
|
TString *documentation;
|
||||||
std::string name;
|
TString *name;
|
||||||
|
|
||||||
uint32_t chunkId;
|
uint32_t chunkId;
|
||||||
};
|
};
|
||||||
class TClass {
|
class TClass {
|
||||||
public:
|
public:
|
||||||
std::string documentation;
|
TString *documentation;
|
||||||
std::vector<std::string> name;
|
std::vector<TString *> name;
|
||||||
std::vector<std::string> inherits;
|
std::vector<TString *> inherits;
|
||||||
std::vector<TClassEntry> entry;
|
std::vector<TClassEntry> entry;
|
||||||
};
|
};
|
||||||
class TClassObjectEntry {
|
class TClassObjectEntry {
|
||||||
@@ -1519,19 +1710,19 @@ class TFile : public THeapObject {
|
|||||||
static TFile *Create(GCList &gc);
|
static TFile *Create(GCList &gc);
|
||||||
std::vector<TFileChunk *> chunks;
|
std::vector<TFileChunk *> chunks;
|
||||||
|
|
||||||
std::vector<std::string> strings;
|
std::vector<TString *> strings;
|
||||||
std::vector<std::pair<std::string, std::string>> vms;
|
std::vector<std::pair<TString *, TString *>> vms;
|
||||||
std::vector<std::pair<std::vector<std::string>, uint32_t>> functions;
|
std::vector<std::pair<std::vector<TString *>, uint32_t>> functions;
|
||||||
std::vector<std::pair<std::string, TVMVersion>> dependencies;
|
std::vector<std::pair<TString *, TVMVersion>> dependencies;
|
||||||
std::vector<std::pair<std::string, TVMVersion>> tools;
|
std::vector<std::pair<TString *, TVMVersion>> tools;
|
||||||
std::vector<std::pair<std::string, std::vector<uint8_t>>> sections;
|
std::vector<std::pair<std::string, std::vector<uint8_t>>> sections;
|
||||||
std::vector<std::pair<std::string, std::vector<uint8_t>>> metadata;
|
std::vector<std::pair<TString *, std::vector<uint8_t>>> metadata;
|
||||||
std::vector<std::vector<uint8_t>> resources;
|
std::vector<TResource *> resources;
|
||||||
std::vector<TClass> classes;
|
std::vector<TClass> classes;
|
||||||
std::string name;
|
TString *name;
|
||||||
TVMVersion version;
|
TVMVersion version;
|
||||||
std::string info;
|
TString *info;
|
||||||
int32_t icon = -1;
|
TResource *icon = nullptr;
|
||||||
|
|
||||||
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);
|
||||||
@@ -1541,10 +1732,10 @@ class TFile : public THeapObject {
|
|||||||
uint8_t *buffer, size_t len);
|
uint8_t *buffer, size_t len);
|
||||||
uint32_t
|
uint32_t
|
||||||
EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
|
EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
|
||||||
std::string
|
void EnsureString(GCList &ls,
|
||||||
EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
|
||||||
|
|
||||||
std::string
|
TString *
|
||||||
GetString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
|
GetString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
|
||||||
void Mark();
|
void Mark();
|
||||||
|
|
||||||
@@ -1570,6 +1761,13 @@ class TAssociativeArray : public THeapObject {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class TList : public THeapObject {
|
class TList : public THeapObject {
|
||||||
|
protected:
|
||||||
|
bool opExecuteMethod(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args);
|
||||||
|
bool opGetField(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TList() = default;
|
TList() = default;
|
||||||
template <typename Itterator>
|
template <typename Itterator>
|
||||||
@@ -1577,10 +1775,7 @@ class TList : public THeapObject {
|
|||||||
TList(std::initializer_list<TObject> il) : items(il) {}
|
TList(std::initializer_list<TObject> il) : items(il) {}
|
||||||
TList(int64_t capacity) { items.reserve(capacity); }
|
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);
|
|
||||||
[[deprecated("Use GCList::Create<T>() instead")]]
|
|
||||||
static TList *Create(GCList &gc);
|
|
||||||
template <typename Itterator>
|
template <typename Itterator>
|
||||||
[[deprecated("Use GCList::Create<T>() instead")]]
|
[[deprecated("Use GCList::Create<T>() instead")]]
|
||||||
static TList *Create(GCList *gc, Itterator begin, Itterator end) {
|
static TList *Create(GCList *gc, Itterator begin, Itterator end) {
|
||||||
@@ -1599,6 +1794,7 @@ class TList : public THeapObject {
|
|||||||
static TList *Create(GCList &gc, std::initializer_list<TObject> il) {
|
static TList *Create(GCList &gc, std::initializer_list<TObject> il) {
|
||||||
return gc.Create<TList>(il);
|
return gc.Create<TList>(il);
|
||||||
}
|
}
|
||||||
|
std::string TypeName();
|
||||||
virtual int64_t Count();
|
virtual int64_t Count();
|
||||||
virtual TObject Get(int64_t index);
|
virtual TObject Get(int64_t index);
|
||||||
virtual void Set(int64_t index, TObject value);
|
virtual void Set(int64_t index, TObject value);
|
||||||
@@ -2235,7 +2431,7 @@ class TDynamicList : public THeapObject {
|
|||||||
TObject Remove(GCList &ls, TObject v);
|
TObject Remove(GCList &ls, TObject v);
|
||||||
TObject RemoveAt(GCList &ls, int64_t v);
|
TObject RemoveAt(GCList &ls, int64_t v);
|
||||||
TObject Clear(GCList &ls);
|
TObject Clear(GCList &ls);
|
||||||
TObject ToString(GCList &ls);
|
TString *ToString(GCList &ls);
|
||||||
|
|
||||||
~TDynamicList();
|
~TDynamicList();
|
||||||
};
|
};
|
||||||
@@ -2449,12 +2645,64 @@ class TNativeObject : public THeapObject {
|
|||||||
return ls->Create<T>(std::forward<TArgs>(args)...);
|
return ls->Create<T>(std::forward<TArgs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TObject CallMethod(GCList &ls, std::string name,
|
virtual TObject CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
std::vector<TObject> args) = 0;
|
const std::string &name,
|
||||||
virtual std::string TypeName() = 0;
|
const std::vector<TObject> &args) = 0;
|
||||||
virtual bool ToBool();
|
|
||||||
virtual bool Equals(std::shared_ptr<GC> gc, TObject right);
|
|
||||||
};
|
};
|
||||||
|
class ITStream : public TNativeObject {
|
||||||
|
protected:
|
||||||
|
bool Exists(std::string_view str);
|
||||||
|
|
||||||
|
public:
|
||||||
|
TObject CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args);
|
||||||
|
std::string TypeName();
|
||||||
|
virtual std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream() = 0;
|
||||||
|
};
|
||||||
|
class TObjectStreamWrapper : public ITStream {
|
||||||
|
std::shared_ptr<TObjectStream> strm;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TObjectStreamWrapper(std::shared_ptr<TObjectStream> strm);
|
||||||
|
TObject CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args);
|
||||||
|
std::string TypeName();
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
|
||||||
|
};
|
||||||
|
class TStream : public ITStream {
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TMemoryStream : public ITStream {
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::MemoryStream> strm;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TMemoryStream(
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::MemoryStream> strm);
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
|
||||||
|
TObject CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args);
|
||||||
|
std::string TypeName();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TNetworkStream : public ITStream {
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::NetworkStream> strm;
|
||||||
|
TNetworkStream(
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::NetworkStream> strm);
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
|
||||||
|
TObject CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args);
|
||||||
|
std::string TypeName();
|
||||||
|
};
|
||||||
|
|
||||||
class TRandom : public TNativeObject {
|
class TRandom : public TNativeObject {
|
||||||
public:
|
public:
|
||||||
Tesses::Framework::Random random;
|
Tesses::Framework::Random random;
|
||||||
@@ -2565,7 +2813,7 @@ class SyntaxException : public std::exception {
|
|||||||
LexTokenLineInfo LineInfo() { return line; }
|
LexTokenLineInfo LineInfo() { return line; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> bool GetObject(TObject &obj, T &res) {
|
template <typename T> bool GetObject(const TObject &obj, T &res) {
|
||||||
if (!std::holds_alternative<T>(obj))
|
if (!std::holds_alternative<T>(obj))
|
||||||
return false;
|
return false;
|
||||||
res = std::get<T>(obj);
|
res = std::get<T>(obj);
|
||||||
@@ -2580,20 +2828,34 @@ inline bool IsNull(const TObject &obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[deprecated("Use GetObjectHeap() with TString instead")]]
|
[[deprecated("Use GetObjectHeap() with TString instead")]]
|
||||||
inline bool GetObject(TObject &obj, std::string &str) {
|
inline bool GetObject(const TObject &obj, std::string &str) {
|
||||||
if (!std::holds_alternative<std::string>(obj))
|
if (!std::holds_alternative<std::string>(obj))
|
||||||
return false;
|
return false;
|
||||||
str = std::get<std::string>(obj);
|
str = std::get<std::string>(obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename T,
|
||||||
|
std::enable_if_t<std::is_base_of_v<Tesses::Framework::Streams::Stream, T>,
|
||||||
|
int> = 0>
|
||||||
|
bool GetObject(const TObject &obj, std::shared_ptr<T> &ptr) {
|
||||||
|
ITStream *strm;
|
||||||
|
if (!GetObjectHeap(obj, strm))
|
||||||
|
return false;
|
||||||
|
auto res = std::dynamic_pointer_cast<T>(strm->GetStream());
|
||||||
|
if (!res)
|
||||||
|
return false;
|
||||||
|
ptr = res;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool GetArgument(std::vector<TObject> &args, size_t index, T &obj) {
|
bool GetArgument(const std::vector<TObject> &args, size_t index, T &obj) {
|
||||||
if (index >= args.size())
|
if (index >= args.size())
|
||||||
return false;
|
return false;
|
||||||
return GetObject(args[index], obj);
|
return GetObject(args[index], obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool GetObjectHeap(TObject &obj, T &res) {
|
template <typename T> bool GetObjectHeap(TObject &obj, T &res) {
|
||||||
THeapObject *h;
|
THeapObject *h;
|
||||||
if (!GetObject<THeapObject *>(obj, h))
|
if (!GetObject<THeapObject *>(obj, h))
|
||||||
@@ -2606,7 +2868,7 @@ template <typename T> bool GetObjectHeap(TObject &obj, T &res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool GetArgumentHeap(std::vector<TObject> &args, size_t index, T &obj) {
|
bool GetArgumentHeap(const std::vector<TObject> &args, size_t index, T &obj) {
|
||||||
if (index >= args.size())
|
if (index >= args.size())
|
||||||
return false;
|
return false;
|
||||||
return GetObjectHeap(args[index], obj);
|
return GetObjectHeap(args[index], obj);
|
||||||
@@ -2616,8 +2878,8 @@ bool GetObjectAsPath(TObject &obj, Tesses::Framework::Filesystem::VFSPath &path,
|
|||||||
bool GetArgumentAsPath(std::vector<TObject> &args, size_t index,
|
bool GetArgumentAsPath(std::vector<TObject> &args, size_t index,
|
||||||
Tesses::Framework::Filesystem::VFSPath &path,
|
Tesses::Framework::Filesystem::VFSPath &path,
|
||||||
bool allowString = true);
|
bool allowString = true);
|
||||||
bool ToBool(TObject obj);
|
bool ObjectToBool(TObject obj);
|
||||||
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right);
|
bool ObjectEquals(std::shared_ptr<GC> gc, TObject left, TObject right);
|
||||||
typedef void (*PluginFunction)(std::shared_ptr<GC> gc, TRootEnvironment *env);
|
typedef void (*PluginFunction)(std::shared_ptr<GC> gc, TRootEnvironment *env);
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
#define DLLEXPORT
|
#define DLLEXPORT
|
||||||
@@ -2662,11 +2924,10 @@ ToHttpServer(std::shared_ptr<GC> gc, TObject obj);
|
|||||||
|
|
||||||
class EmbedStream : public Tesses::Framework::Streams::Stream {
|
class EmbedStream : public Tesses::Framework::Streams::Stream {
|
||||||
size_t offset;
|
size_t offset;
|
||||||
MarkedTObject file;
|
MarkedTObject resource;
|
||||||
uint32_t resource;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EmbedStream(std::shared_ptr<GC> gc, TFile *file, uint32_t resource);
|
EmbedStream(std::shared_ptr<GC> gc, TResource *res);
|
||||||
bool CanRead();
|
bool CanRead();
|
||||||
bool CanSeek();
|
bool CanSeek();
|
||||||
bool EndOfStream();
|
bool EndOfStream();
|
||||||
|
|||||||
@@ -1865,6 +1865,8 @@ SyntaxNode Parser::ParseBAnd() {
|
|||||||
SyntaxNode Parser::ParseExpression() {
|
SyntaxNode Parser::ParseExpression() {
|
||||||
SyntaxNode expr = ParseAssignment();
|
SyntaxNode expr = ParseAssignment();
|
||||||
while (IsSymbol(",")) {
|
while (IsSymbol(",")) {
|
||||||
|
if (IsAnySymbol({"]", "}"}, false))
|
||||||
|
break;
|
||||||
expr = AdvancedSyntaxNode::Create(CommaExpression, true,
|
expr = AdvancedSyntaxNode::Create(CommaExpression, true,
|
||||||
{expr, ParseAssignment()});
|
{expr, ParseAssignment()});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
|
|||||||
env->LoadFileWithDependencies(
|
env->LoadFileWithDependencies(
|
||||||
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
|
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
|
||||||
|
|
||||||
TList *args = TList::Create(ls);
|
TList *args = ls.Create<TList>();
|
||||||
|
|
||||||
args->Add(filename.ToString());
|
args->Add(filename.ToString());
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ TObject CrossLangInterperter(GCList &ls, TRootEnvironment *env,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TList *args = TList::Create(ls);
|
TList *args = ls.Create<TList>();
|
||||||
for (int arg = 1; arg < argv.size(); arg++)
|
for (int arg = 1; arg < argv.size(); arg++)
|
||||||
args->Add(std::string(argv[arg]));
|
args->Add(std::string(argv[arg]));
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
|
|||||||
|
|
||||||
env->EnsureDictionary(ls.GetGC(), "Net")
|
env->EnsureDictionary(ls.GetGC(), "Net")
|
||||||
->SetValue("WebServerPort", (int64_t)port);
|
->SetValue("WebServerPort", (int64_t)port);
|
||||||
TList *args2 = TList::Create(ls);
|
TList *args2 = ls.Create<TList>();
|
||||||
for (auto &item : args.positional) {
|
for (auto &item : args.positional) {
|
||||||
args2->Add(item);
|
args2->Add(item);
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
|
|||||||
TF_Quit();
|
TF_Quit();
|
||||||
return (int64_t)0;
|
return (int64_t)0;
|
||||||
} else {
|
} else {
|
||||||
TList *args = TList::Create(ls);
|
TList *args = ls.Create<TList>();
|
||||||
for (size_t arg = 1; arg < argv.size(); arg++)
|
for (size_t arg = 1; arg < argv.size(); arg++)
|
||||||
args->Add(std::string(argv[arg]));
|
args->Add(std::string(argv[arg]));
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
|
static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for (auto &item : strs)
|
for (auto &item : strs)
|
||||||
list->Add(item);
|
list->Add(item);
|
||||||
@@ -10,7 +10,7 @@ static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
static TList *EntriesToList(GCList &ls, std::vector<TClassEntry> &ents) {
|
static TList *EntriesToList(GCList &ls, std::vector<TClassEntry> &ents) {
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for (auto &item : ents) {
|
for (auto &item : ents) {
|
||||||
std::string modifier = "public";
|
std::string modifier = "public";
|
||||||
@@ -42,7 +42,7 @@ static TList *EntriesToList(GCList &ls, std::vector<TClassEntry> &ents) {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
static TList *ClassInstanceToList(GCList &ls, TClassObject *co) {
|
static TList *ClassInstanceToList(GCList &ls, TClassObject *co) {
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for (auto &item : co->entries) {
|
for (auto &item : co->entries) {
|
||||||
if (item.modifier == TClassModifier::Public) {
|
if (item.modifier == TClassModifier::Public) {
|
||||||
@@ -126,7 +126,7 @@ static TObject Class_CreateInstance(TRootEnvironment *env, GCList &ls,
|
|||||||
}
|
}
|
||||||
static TObject Class_GetClassNames(TRootEnvironment *env, GCList &ls,
|
static TObject Class_GetClassNames(TRootEnvironment *env, GCList &ls,
|
||||||
std::vector<TObject> args) {
|
std::vector<TObject> args) {
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for (auto &item : env->classes) {
|
for (auto &item : env->classes) {
|
||||||
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
|
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
TObject Dictionary_FindByKey(GCList &ls, std::vector<TObject> args) {
|
TObject Dictionary_FindByKey(GCList &ls, std::vector<TObject> args) {
|
||||||
TList *dest = TList::Create(ls);
|
TList *dest = ls.Create<TList>();
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
std::string key;
|
std::string key;
|
||||||
if (GetArgument(args, 1, key)) {
|
if (GetArgument(args, 1, key)) {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ static TObject Env_GetRealExecutablePath(GCList &ls,
|
|||||||
}
|
}
|
||||||
static TObject Env_GetAll(GCList &ls, std::vector<TObject> args) {
|
static TObject Env_GetAll(GCList &ls, std::vector<TObject> args) {
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
std::vector<std::pair<std::string, std::string>> env;
|
std::vector<std::pair<std::string, std::string>> env;
|
||||||
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
|
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
|
||||||
for (auto &item : env) {
|
for (auto &item : env) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ static TObject FS_ReadAllLines(GCList &ls, std::vector<TObject> args) {
|
|||||||
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
|
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
|
||||||
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto items = TList::Create(ls);
|
auto items = ls.Create<TList>();
|
||||||
for (auto &l : lines) {
|
for (auto &l : lines) {
|
||||||
items->Add(l);
|
items->Add(l);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ static TObject JsonDeserialize(GCList &ls2, JToken json) {
|
|||||||
if (TryGetJToken(json, str))
|
if (TryGetJToken(json, str))
|
||||||
return str;
|
return str;
|
||||||
if (TryGetJToken(json, arr)) {
|
if (TryGetJToken(json, arr)) {
|
||||||
TList *ls = TList::Create(ls2);
|
TList *ls = ls2.Create<TList>();
|
||||||
|
|
||||||
for (auto &item : arr) {
|
for (auto &item : arr) {
|
||||||
auto itemRes = JsonDeserialize(ls2, item);
|
auto itemRes = JsonDeserialize(ls2, item);
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ static std::shared_ptr<SMTPBody>
|
|||||||
TObjectToSMTPBody(GCList &ls, std::string mimeType, TObject obj) {
|
TObjectToSMTPBody(GCList &ls, std::string mimeType, TObject obj) {
|
||||||
std::shared_ptr<SMTPBody> body;
|
std::shared_ptr<SMTPBody> body;
|
||||||
std::string text;
|
std::string text;
|
||||||
TByteArray *ba;
|
TByteView *ba;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||||
if (GetObject(obj, text)) {
|
if (GetObject(obj, text)) {
|
||||||
body = std::make_shared<SMTPStringBody>(text, mimeType);
|
body = std::make_shared<SMTPStringBody>(text, mimeType);
|
||||||
} else if (GetObjectHeap(obj, ba)) {
|
} else if (GetObjectHeap(obj, ba)) {
|
||||||
std::shared_ptr<MemoryStream> ms = std::make_shared<MemoryStream>(true);
|
std::shared_ptr<MemoryStream> ms = std::make_shared<MemoryStream>(true);
|
||||||
ms->WriteBlock(ba->data.data(), ba->data.size());
|
ms->WriteBlock(ba->GetData(), ba->GetSize());
|
||||||
ms->Seek(0L, SeekOrigin::Begin);
|
ms->Seek(0L, SeekOrigin::Begin);
|
||||||
|
|
||||||
body = std::make_shared<SMTPStreamBody>(mimeType, ms);
|
body = std::make_shared<SMTPStreamBody>(mimeType, ms);
|
||||||
@@ -191,7 +191,7 @@ class THttpDictionary : public TNativeObject {
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else if (key == "ToList") {
|
} else if (key == "ToList") {
|
||||||
TList *_ls = TList::Create(ls);
|
TList *_ls = ls.Create<TList>();
|
||||||
for (auto item : dict->kvp) {
|
for (auto item : dict->kvp) {
|
||||||
for (auto i : item.second) {
|
for (auto i : item.second) {
|
||||||
auto d = TDictionary::Create(ls);
|
auto d = TDictionary::Create(ls);
|
||||||
@@ -334,7 +334,7 @@ class TServerContext : public TNativeObjectThatReturnsHttpDictionary {
|
|||||||
return strm;
|
return strm;
|
||||||
});
|
});
|
||||||
|
|
||||||
return TList::Create(ls, response.begin(), response.end());
|
return ls.Create<TList>(response.begin(), response.end());
|
||||||
}
|
}
|
||||||
} else if (key == "getNeedToParseFormData")
|
} else if (key == "getNeedToParseFormData")
|
||||||
return ctx->NeedToParseFormData();
|
return ctx->NeedToParseFormData();
|
||||||
@@ -1581,7 +1581,7 @@ void TStd::RegisterNet(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
|||||||
dict->DeclareFunction(
|
dict->DeclareFunction(
|
||||||
gc, "getIPAddresses", "Get the ip addresses of this machine", {"$ipv6"},
|
gc, "getIPAddresses", "Get the ip addresses of this machine", {"$ipv6"},
|
||||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
TList *a = TList::Create(ls);
|
TList *a = ls.Create<TList>();
|
||||||
bool ipv6 = false;
|
bool ipv6 = false;
|
||||||
GetArgument(args, 0, ipv6);
|
GetArgument(args, 0, ipv6);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ namespace Tesses::CrossLang {
|
|||||||
class ProcessObject : public TNativeObject {
|
class ProcessObject : public TNativeObject {
|
||||||
public:
|
public:
|
||||||
ProcessObject(GCList &ls) {
|
ProcessObject(GCList &ls) {
|
||||||
arguments = TList::Create(ls);
|
arguments = ls.Create<TList>();
|
||||||
environment = TList::Create(ls);
|
environment = ls.Create<TList>();
|
||||||
process.includeThisEnv = true;
|
process.includeThisEnv = true;
|
||||||
process.redirectStdIn = false;
|
process.redirectStdIn = false;
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class SQLiteObject : public TNativeObject {
|
|||||||
|
|
||||||
this->db->Exec(arg, res);
|
this->db->Exec(arg, res);
|
||||||
|
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
|
|
||||||
for (auto &item : res) {
|
for (auto &item : res) {
|
||||||
TDictionary *dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ static TObject AstToTObject(GCList &ls, SyntaxNode node) {
|
|||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
r->SetValue("Type", asn.nodeName);
|
r->SetValue("Type", asn.nodeName);
|
||||||
r->SetValue("IsExpression", asn.isExpression);
|
r->SetValue("IsExpression", asn.isExpression);
|
||||||
TList *ls2 = TList::Create(ls);
|
TList *ls2 = ls.Create<TList>();
|
||||||
for (auto item : asn.nodes) {
|
for (auto item : asn.nodes) {
|
||||||
ls2->Add(AstToTObject(ls, item));
|
ls2->Add(AstToTObject(ls, item));
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) {
|
|||||||
auto current_function = GC::GetCurrentFunction();
|
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 = ls.Create<TList>();
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for (auto item : current_function->thread->call_stack_entries) {
|
for (auto item : current_function->thread->call_stack_entries) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
|
|||||||
83
src/types/byteviews/byteview.cpp
Normal file
83
src/types/byteviews/byteview.cpp
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
std::string TByteView::TypeName() { return "ByteView"; }
|
||||||
|
TString *TByteView::ToString(GCList &ls) {
|
||||||
|
auto bounds = GetBounds();
|
||||||
|
if (bounds.first == nullptr || bounds.second == 0)
|
||||||
|
return ls.FromString("");
|
||||||
|
|
||||||
|
return ls.Create<TString>(reinterpret_cast<const char *>(bounds.first),
|
||||||
|
bounds.second);
|
||||||
|
}
|
||||||
|
bool TByteView::opExecuteMethod(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args) {
|
||||||
|
if (name == "Slice") {
|
||||||
|
int64_t offset = 0;
|
||||||
|
int64_t length = -1;
|
||||||
|
|
||||||
|
GetArgument(args, 0, offset);
|
||||||
|
GetArgument(args, 1, length);
|
||||||
|
|
||||||
|
GCList ls(gc);
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(
|
||||||
|
gc, ls.Create<TSpan>(this, offset, length));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name == "Count" || name == "Length") {
|
||||||
|
thrd->call_stack_entries.back()->Push(
|
||||||
|
gc, static_cast<int64_t>(this->GetBounds().second));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name == "GetAt") {
|
||||||
|
int64_t i64;
|
||||||
|
if (GetArgument(args, 0, i64)) {
|
||||||
|
auto res = this->GetAt(static_cast<size_t>(i64));
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(
|
||||||
|
gc, res == -1 ? static_cast<TObject>(nullptr)
|
||||||
|
: static_cast<TObject>(res));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TByteView::opGetField(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name) {
|
||||||
|
if (name == "Count" || name == "Length") {
|
||||||
|
thrd->call_stack_entries.back()->Push(
|
||||||
|
gc, static_cast<int64_t>(this->GetBounds().second));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void TByteView::CopyTo(TMutByteView *view) {
|
||||||
|
auto myBounds = this->GetBounds();
|
||||||
|
if (myBounds.first == nullptr || myBounds.second == 0)
|
||||||
|
return;
|
||||||
|
auto theirBounds = view->GetMutableBoundsConstrained(0, myBounds.second);
|
||||||
|
|
||||||
|
if (theirBounds.first == nullptr || theirBounds.second == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(theirBounds.first, myBounds.first, theirBounds.second);
|
||||||
|
}
|
||||||
|
void TByteView::CopyTo(TMutByteView *view, size_t srcOffset, size_t destOffset,
|
||||||
|
size_t length) {
|
||||||
|
auto myBounds = this->GetBoundsConstrained(srcOffset, length);
|
||||||
|
if (myBounds.first == nullptr || myBounds.second == 0)
|
||||||
|
return;
|
||||||
|
auto theirBounds =
|
||||||
|
view->GetMutableBoundsConstrained(destOffset, myBounds.second);
|
||||||
|
|
||||||
|
if (theirBounds.first == nullptr || theirBounds.second == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(theirBounds.first, myBounds.first, theirBounds.second);
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
0
src/types/byteviews/mutbyteview.cpp
Normal file
0
src/types/byteviews/mutbyteview.cpp
Normal file
10
src/types/byteviews/resource.cpp
Normal file
10
src/types/byteviews/resource.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
TResource::TResource(std::vector<uint8_t> &&bytes) : bytes(std::move(bytes)) {}
|
||||||
|
std::pair<const uint8_t *, size_t> TResource::GetBounds() const {
|
||||||
|
return std::pair<const uint8_t *, size_t>(bytes.data(), bytes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TResource::TypeName() { return "Resource"; }
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
123
src/types/byteviews/string.cpp
Normal file
123
src/types/byteviews/string.cpp
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
|
||||||
|
TString::TString() {}
|
||||||
|
TString::TString(std::string_view str) : text(str) {}
|
||||||
|
TString::TString(const char *text, size_t len) : text(text, len) {}
|
||||||
|
TString::TString(std::string_view left, std::string_view right) {
|
||||||
|
text.reserve(left.size() + right.size());
|
||||||
|
text.append(left.begin(), left.end());
|
||||||
|
text.append(right.begin(), right.end());
|
||||||
|
}
|
||||||
|
TString::TString(std::string &&str) : text(std::move(str)) {}
|
||||||
|
|
||||||
|
const std::string &TString::GetString() const { return this->text; }
|
||||||
|
|
||||||
|
std::pair<const uint8_t *, size_t> TString::GetBounds() const {
|
||||||
|
return std::pair<const uint8_t *, size_t>(
|
||||||
|
reinterpret_cast<const uint8_t *>(text.data()), text.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TString::TypeName() { return "String"; }
|
||||||
|
|
||||||
|
TString *TString::ToString(GCList &ls) {
|
||||||
|
ls.Add(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TString::opAdd(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs) {
|
||||||
|
TString *rStr;
|
||||||
|
char rChr;
|
||||||
|
if (GetObjectHeap(rhs, rStr)) {
|
||||||
|
GCList ls(gc);
|
||||||
|
thrd->call_stack_entries.back()->Push(
|
||||||
|
gc, ls.Create<TString>(this->GetString(), rStr->GetString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (GetObject(rhs, rChr)) {
|
||||||
|
GCList ls(gc);
|
||||||
|
thrd->call_stack_entries.back()->Push(
|
||||||
|
gc,
|
||||||
|
ls.Create<TString>(this->GetString(), std::string_view(&rChr, 1)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TString::opLessThan(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs) {
|
||||||
|
|
||||||
|
TString *rStr;
|
||||||
|
if (GetObjectHeap(rhs, rStr)) {
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, this->GetString() <
|
||||||
|
rStr->GetString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TString::opGreaterThan(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs) {
|
||||||
|
|
||||||
|
TString *rStr;
|
||||||
|
if (GetObjectHeap(rhs, rStr)) {
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, this->GetString() >
|
||||||
|
rStr->GetString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TString::opLessThanEqual(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
TObject rhs) {
|
||||||
|
|
||||||
|
TString *rStr;
|
||||||
|
if (GetObjectHeap(rhs, rStr)) {
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, this->GetString() <=
|
||||||
|
rStr->GetString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TString::opGreaterThanEqual(InterperterThread *thrd,
|
||||||
|
std::shared_ptr<GC> gc, TObject rhs) {
|
||||||
|
|
||||||
|
TString *rStr;
|
||||||
|
if (GetObjectHeap(rhs, rStr)) {
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, this->GetString() >=
|
||||||
|
rStr->GetString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
thrd->call_stack_entries.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TString::IsEqualTo(std::shared_ptr<GC> gc, TObject rhs) {
|
||||||
|
TString *rStr;
|
||||||
|
if (GetObjectHeap(rhs, rStr)) {
|
||||||
|
if (this == rStr)
|
||||||
|
return true;
|
||||||
|
return this->GetString() == rStr->GetString();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TString::IsNotEqualTo(std::shared_ptr<GC> gc, TObject rhs) {
|
||||||
|
TString *rStr;
|
||||||
|
if (GetObjectHeap(rhs, rStr)) {
|
||||||
|
if (this == rStr)
|
||||||
|
return false;
|
||||||
|
return this->GetString() != rStr->GetString();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -9,7 +9,7 @@ TArgWrapper *TArgWrapper::Create(GCList *ls, TCallable *callable) {
|
|||||||
}
|
}
|
||||||
TObject TArgWrapper::Call(GCList &ls, std::vector<TObject> args) {
|
TObject TArgWrapper::Call(GCList &ls, std::vector<TObject> args) {
|
||||||
auto cse = GC::GetCurrentFunction();
|
auto cse = GC::GetCurrentFunction();
|
||||||
TList *argList = TList::Create(ls);
|
TList *argList = ls.Create<TList>();
|
||||||
argList->items = args;
|
argList->items = args;
|
||||||
TObject v = this->callable->Call(ls, {argList});
|
TObject v = this->callable->Call(ls, {argList});
|
||||||
GC::SetCurrentFunction(cse);
|
GC::SetCurrentFunction(cse);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ TObject TDynamicDictionary::CallMethod(GCList &ls, std::string name,
|
|||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "CallMethod");
|
dict->SetValue("Type", "CallMethod");
|
||||||
dict->SetValue("Name", name);
|
dict->SetValue("Name", name);
|
||||||
auto argVal = TList::Create(ls);
|
auto argVal = ls.Create<TList>();
|
||||||
argVal->items = args;
|
argVal->items = args;
|
||||||
dict->SetValue("Arguments", argVal);
|
dict->SetValue("Arguments", argVal);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ int64_t TDynamicList::Count(GCList &ls) {
|
|||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Count");
|
dict->SetValue("Type", ls.FromString("Count"));
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
auto res = cb->Call(ls, {dict});
|
auto res = cb->Call(ls, {dict});
|
||||||
int64_t n;
|
int64_t n;
|
||||||
@@ -31,7 +31,7 @@ TObject TDynamicList::Add(GCList &ls, TObject v) {
|
|||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Add");
|
dict->SetValue("Type", ls.FromString("Add"));
|
||||||
dict->SetValue("Value", v);
|
dict->SetValue("Value", v);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls, {dict});
|
return cb->Call(ls, {dict});
|
||||||
@@ -40,7 +40,7 @@ TObject TDynamicList::Insert(GCList &ls, int64_t index, TObject v) {
|
|||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Insert");
|
dict->SetValue("Type", ls.FromString("Insert"));
|
||||||
dict->SetValue("Index", index);
|
dict->SetValue("Index", index);
|
||||||
dict->SetValue("Value", v);
|
dict->SetValue("Value", v);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
@@ -49,14 +49,14 @@ TObject TDynamicList::Insert(GCList &ls, int64_t index, TObject v) {
|
|||||||
TObject TDynamicList::Clear(GCList &ls) {
|
TObject TDynamicList::Clear(GCList &ls) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Clear");
|
dict->SetValue("Type", ls.FromString("Clear"));
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls, {dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
TObject TDynamicList::Remove(GCList &ls, TObject obj) {
|
TObject TDynamicList::Remove(GCList &ls, TObject obj) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Remove");
|
dict->SetValue("Type", ls.FromString("Remove"));
|
||||||
dict->SetValue("Value", obj);
|
dict->SetValue("Value", obj);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ TObject TDynamicList::Remove(GCList &ls, TObject obj) {
|
|||||||
TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
|
TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "RemoveAllEqual");
|
dict->SetValue("Type", ls.FromString("RemoveAllEqual"));
|
||||||
dict->SetValue("Value", obj);
|
dict->SetValue("Value", obj);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
|
|||||||
TObject TDynamicList::RemoveAt(GCList &ls, int64_t index) {
|
TObject TDynamicList::RemoveAt(GCList &ls, int64_t index) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "RemoveAt");
|
dict->SetValue("Type", ls.FromString("RemoveAt"));
|
||||||
dict->SetValue("Index", index);
|
dict->SetValue("Index", index);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ TObject TDynamicList::RemoveAt(GCList &ls, int64_t index) {
|
|||||||
TObject TDynamicList::ToString(GCList &ls) {
|
TObject TDynamicList::ToString(GCList &ls) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "ToString");
|
dict->SetValue("Type", ls.FromString("ToString"));
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return cb->Call(ls, {dict});
|
return cb->Call(ls, {dict});
|
||||||
@@ -93,7 +93,7 @@ TObject TDynamicList::GetAt(GCList &ls, int64_t index) {
|
|||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "GetAt");
|
dict->SetValue("Type", ls.FromString("GetAt"));
|
||||||
dict->SetValue("Index", index);
|
dict->SetValue("Index", index);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls, {dict});
|
return cb->Call(ls, {dict});
|
||||||
@@ -102,7 +102,7 @@ TObject TDynamicList::GetAt(GCList &ls, int64_t index) {
|
|||||||
TObject TDynamicList::SetAt(GCList &ls, int64_t index, TObject val) {
|
TObject TDynamicList::SetAt(GCList &ls, int64_t index, TObject val) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "SetAt");
|
dict->SetValue("Type", ls.FromString("SetAt"));
|
||||||
dict->SetValue("Index", index);
|
dict->SetValue("Index", index);
|
||||||
dict->SetValue("Value", val);
|
dict->SetValue("Value", val);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
@@ -114,8 +114,7 @@ TDynamicList::~TDynamicList() {}
|
|||||||
TByteArray *TByteArray::Create(GCList &ls) { return ls.Create<TByteArray>(); }
|
TByteArray *TByteArray::Create(GCList &ls) { return ls.Create<TByteArray>(); }
|
||||||
|
|
||||||
TByteArray *TByteArray::Create(GCList *ls) { return ls->Create<TByteArray>(); }
|
TByteArray *TByteArray::Create(GCList *ls) { return ls->Create<TByteArray>(); }
|
||||||
TList *TList::Create(GCList *gc) { return gc->Create<TList>(); }
|
|
||||||
TList *TList::Create(GCList &gc) { return gc.Create<TList>(); }
|
|
||||||
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()) {
|
||||||
@@ -148,4 +147,201 @@ void TList::Mark() {
|
|||||||
GC::Mark(item);
|
GC::Mark(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::string TList::TypeName() { return "List"; }
|
||||||
|
bool TList::opGetField(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name) {
|
||||||
|
auto &cse = thrd->call_stack_entries;
|
||||||
|
if (name == "Count" || name == "Length") {
|
||||||
|
int64_t len = this->Count();
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
cse.back()->Push(gc, len);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TList::opExecuteMethod(InterperterThread *thrd, std::shared_ptr<GC> gc,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args) {
|
||||||
|
|
||||||
|
auto &cse = thrd->call_stack_entries;
|
||||||
|
GCList ls(gc);
|
||||||
|
|
||||||
|
if (name == "GetEnumerator") {
|
||||||
|
cse.back()->Push(gc, ls.Create<TListEnumerator>(this));
|
||||||
|
return false;
|
||||||
|
} else if (name == "ToString") {
|
||||||
|
|
||||||
|
cse.back()->Push(gc, Json_Encode(this));
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if (name == "Insert") {
|
||||||
|
if (args.size() != 2) {
|
||||||
|
throw VMException("List.Insert must only accept two arguments");
|
||||||
|
}
|
||||||
|
int64_t index;
|
||||||
|
|
||||||
|
if (!GetArgument(args, 0, index)) {
|
||||||
|
throw VMException("List.Insert first argument must be Long");
|
||||||
|
}
|
||||||
|
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->Insert(index, args[1]);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
} else if (name == "Add") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw VMException("List.Add must only accept one argument");
|
||||||
|
}
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->Add(args[0]);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
} else if (name == "Contains") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw VMException("List.Contains must only accept one argument");
|
||||||
|
}
|
||||||
|
gc->BarrierBegin();
|
||||||
|
for (int64_t i = 0; i < this->Count(); i++) {
|
||||||
|
auto item = this->Get(i);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
if (Equals(gc, args[0], item)) {
|
||||||
|
cse.back()->Push(gc, true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
gc->BarrierBegin();
|
||||||
|
}
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, false);
|
||||||
|
return false;
|
||||||
|
} else if (name == "IndexOf") {
|
||||||
|
// IndexOf(obj, $idx)
|
||||||
|
if (args.size() < 1 || args.size() > 2) {
|
||||||
|
throw VMException("List.IndexOf must either have one "
|
||||||
|
"or two arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t i = 0;
|
||||||
|
|
||||||
|
GetArgument(args, 1, i);
|
||||||
|
gc->BarrierBegin();
|
||||||
|
for (; i < this->Count(); i++) {
|
||||||
|
auto item = this->Get(i);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
if (Equals(gc, args[0], item)) {
|
||||||
|
|
||||||
|
cse.back()->Push(gc, i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
gc->BarrierBegin();
|
||||||
|
}
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, (int64_t)-1);
|
||||||
|
return false;
|
||||||
|
} else if (name == "RemoveAllEqual") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw VMException("List.RemoveAllEqual must only "
|
||||||
|
"accept one argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
gc->BarrierBegin();
|
||||||
|
for (int64_t i = 0; i < this->Count(); i++) {
|
||||||
|
auto item = this->Get(i);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
if (Equals(gc, args[0], item)) {
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->RemoveAt(i);
|
||||||
|
i--;
|
||||||
|
} else
|
||||||
|
gc->BarrierBegin();
|
||||||
|
}
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
} else if (name == "Remove") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw VMException("List.Remove must only accept one argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
gc->BarrierBegin();
|
||||||
|
for (int64_t i = 0; i < this->Count(); i++) {
|
||||||
|
auto item = this->Get(i);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
if (Equals(gc, args[0], item)) {
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->RemoveAt(i);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gc->BarrierBegin();
|
||||||
|
}
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
} else if (name == "RemoveAt") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw VMException("List.RemoveAt must only accept one argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::holds_alternative<int64_t>(args[0])) {
|
||||||
|
throw VMException("List.RemoveAt must only accept a long");
|
||||||
|
}
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->RemoveAt(std::get<int64_t>(args[0]));
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
} else if (name == "Clear") {
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->Clear();
|
||||||
|
gc->BarrierEnd();
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
} else if (name == "GetAt") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw VMException("List.GetAt must only accept one argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::holds_alternative<int64_t>(args[0])) {
|
||||||
|
throw VMException("List.GetAt must only accept a long");
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t index = std::get<int64_t>(args[0]);
|
||||||
|
if (index >= 0 && index < this->Count()) {
|
||||||
|
cse.back()->Push(gc, this->Get(index));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (name == "SetAt") {
|
||||||
|
if (args.size() != 2) {
|
||||||
|
throw VMException("List.SetAt must only accept two arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::holds_alternative<int64_t>(args[0])) {
|
||||||
|
throw VMException("List.SetAt first argument must only "
|
||||||
|
"accept a long");
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t index = std::get<int64_t>(args[0]);
|
||||||
|
if (index >= 0 && index < this->Count()) {
|
||||||
|
this->Set(index, args[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (name == "Count" || name == "Length") {
|
||||||
|
gc->BarrierBegin();
|
||||||
|
cse.back()->Push(gc, this->Count());
|
||||||
|
gc->BarrierEnd();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace Tesses::CrossLang
|
}; // namespace Tesses::CrossLang
|
||||||
@@ -32,7 +32,7 @@ TList *TQueryable::ToList(GCList &ls) {
|
|||||||
auto enumerator = this->GetEnumerator(ls);
|
auto enumerator = this->GetEnumerator(ls);
|
||||||
if (enumerator == nullptr)
|
if (enumerator == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto list = TList::Create(ls);
|
auto list = ls.Create<TList>();
|
||||||
while (enumerator->MoveNext(gc)) {
|
while (enumerator->MoveNext(gc)) {
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
list->Add(enumerator->GetCurrent(ls));
|
list->Add(enumerator->GetCurrent(ls));
|
||||||
|
|||||||
30
src/types/streams/memorystream.cpp
Normal file
30
src/types/streams/memorystream.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
TMemoryStream::TMemoryStream(
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::MemoryStream> strm)
|
||||||
|
: strm(strm) {}
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> TMemoryStream::GetStream() {
|
||||||
|
return this->strm;
|
||||||
|
}
|
||||||
|
TObject TMemoryStream::CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args) {
|
||||||
|
if (name == "GetBytes") {
|
||||||
|
return ls.Create<TMemoryStreamMutByteView>(strm);
|
||||||
|
}
|
||||||
|
return ITStream::CallMethod(thrd, ls, name, args);
|
||||||
|
}
|
||||||
|
TMemoryStreamMutByteView::TMemoryStreamMutByteView(
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::MemoryStream> strm)
|
||||||
|
: strm(strm) {}
|
||||||
|
std::pair<uint8_t *, size_t> TMemoryStreamMutByteView::GetMutableBounds() {
|
||||||
|
if (!strm)
|
||||||
|
return std::pair<uint8_t *, size_t>(nullptr, 0);
|
||||||
|
auto &buff = strm->GetBuffer();
|
||||||
|
return std::pair<uint8_t *, size_t>(buff.data(), buff.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TMemoryStream::TypeName() { return "MemoryStream"; }
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
165
src/types/streams/networkstream.cpp
Normal file
165
src/types/streams/networkstream.cpp
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
TNetworkStream::TNetworkStream(
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::NetworkStream> strm)
|
||||||
|
: strm(strm) {}
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream>
|
||||||
|
TNetworkStream::GetStream() {
|
||||||
|
return this->strm;
|
||||||
|
}
|
||||||
|
TObject TNetworkStream::CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args) {
|
||||||
|
int64_t n0;
|
||||||
|
bool bc;
|
||||||
|
if (name == "setBroadcast" && GetArgument(args, 0, bc))
|
||||||
|
strm->SetBroadcast(bc);
|
||||||
|
if (name == "setNoDelay" && GetArgument(args, 0, bc))
|
||||||
|
strm->SetNoDelay(bc);
|
||||||
|
if (name == "setReuseAddress" && GetArgument(args, 0, bc))
|
||||||
|
strm->SetReuseAddress(bc);
|
||||||
|
if (name == "setReusePort" && GetArgument(args, 0, bc))
|
||||||
|
strm->SetReusePort(bc);
|
||||||
|
if (name == "MulticastTTL" && GetArgument(args, 0, n0))
|
||||||
|
strm->SetMulticastTTL((uint8_t)n0);
|
||||||
|
if (name == "getPort" || name == "GetPort") {
|
||||||
|
return (int64_t)strm->GetPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == "SetMulticastMembership") {
|
||||||
|
std::string ma;
|
||||||
|
std::string ifaceIP = "0.0.0.0";
|
||||||
|
if (GetArgument(args, 0, ma)) {
|
||||||
|
GetArgument(args, 1, ifaceIP);
|
||||||
|
strm->SetMulticastMembership(ma, ifaceIP);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
if (name == "Bind") {
|
||||||
|
std::string ip;
|
||||||
|
int64_t port;
|
||||||
|
if (GetArgument(args, 0, ip) && GetArgument(args, 1, port))
|
||||||
|
strm->Bind(ip, (uint16_t)port);
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == "Accept") {
|
||||||
|
std::string ip;
|
||||||
|
uint16_t port;
|
||||||
|
auto strm2 = strm->Accept(ip, port);
|
||||||
|
|
||||||
|
if (strm2 ==
|
||||||
|
nullptr) // just in case, so we don't get a bugged TNetworkStream
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
std::array list = {
|
||||||
|
TDItem("IP", ls.FromString(ip)),
|
||||||
|
TDItem("Port", (int64_t)port),
|
||||||
|
TDItem("Stream", ls.Create<TNetworkStream>(strm2)),
|
||||||
|
};
|
||||||
|
|
||||||
|
return ls.Create<TDictionary>(list.begin(), list.end());
|
||||||
|
}
|
||||||
|
if (name == "Listen") {
|
||||||
|
int64_t backlog;
|
||||||
|
if (GetArgument(args, 0, backlog)) {
|
||||||
|
strm->Listen((int32_t)backlog);
|
||||||
|
} else {
|
||||||
|
strm->Listen(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
if (name == "ReadFrom") {
|
||||||
|
TByteArray *data;
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
|
||||||
|
if (name == "Read") {
|
||||||
|
TMutByteView *bytes;
|
||||||
|
if (GetArgumentHeap(args, 0, bytes)) {
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
if (GetArgument(args, 1, offset) &&
|
||||||
|
GetArgument(args, 2, length)) {
|
||||||
|
auto safe = bytes->GetMutableBoundsConstrained(
|
||||||
|
(size_t)offset, (size_t)length);
|
||||||
|
if (safe.first != nullptr) {
|
||||||
|
std::string ip = {};
|
||||||
|
uint16_t port = 0;
|
||||||
|
auto read =
|
||||||
|
strm->ReadFrom(safe.first, safe.second, ip, port);
|
||||||
|
std::array list = {
|
||||||
|
TDItem("IP", ls.FromString(ip)),
|
||||||
|
TDItem("Port", (int64_t)port),
|
||||||
|
TDItem("Read", (int64_t)read),
|
||||||
|
};
|
||||||
|
return ls.Create<TDictionary>(list.begin(), list.end());
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bounds = bytes->GetMutableBounds();
|
||||||
|
|
||||||
|
if (bounds.first) {
|
||||||
|
std::string ip = {};
|
||||||
|
uint16_t port = 0;
|
||||||
|
auto read =
|
||||||
|
strm->ReadFrom(bounds.first, bounds.second, ip, port);
|
||||||
|
std::array list = {
|
||||||
|
TDItem("IP", ls.FromString(ip)),
|
||||||
|
TDItem("Port", (int64_t)port),
|
||||||
|
TDItem("Read", (int64_t)read),
|
||||||
|
};
|
||||||
|
return ls.Create<TDictionary>(list.begin(), list.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name == "WriteTo") {
|
||||||
|
|
||||||
|
// strm->WriteTo(buff, ip, port)
|
||||||
|
// strm->WriteTo(buff, off, len, ip, port)
|
||||||
|
|
||||||
|
TByteView *bytes;
|
||||||
|
if (GetArgumentHeap(args, 0, bytes)) {
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
TString *ip;
|
||||||
|
int64_t port;
|
||||||
|
if (GetArgument(args, 1, offset) && GetArgument(args, 2, length)) {
|
||||||
|
if (!(GetArgumentHeap(args, 3, ip) &&
|
||||||
|
GetArgument(args, 4, port)))
|
||||||
|
return Undefined();
|
||||||
|
auto safe =
|
||||||
|
bytes->GetBoundsConstrained((size_t)offset, (size_t)length);
|
||||||
|
if (safe.first != nullptr) {
|
||||||
|
return strm->WriteTo(safe.first, safe.second,
|
||||||
|
ip->GetString(), (uint16_t)port);
|
||||||
|
} else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (!(GetArgumentHeap(args, 1, ip) && GetArgument(args, 2, port)))
|
||||||
|
return Undefined();
|
||||||
|
auto bounds = bytes->GetBounds();
|
||||||
|
|
||||||
|
if (bounds.first) {
|
||||||
|
|
||||||
|
return (int64_t)strm->WriteTo(bounds.first, bounds.second,
|
||||||
|
ip->GetString(), (uint16_t)port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ITStream::CallMethod(thrd, ls, name, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TNetworkStream::TypeName() { return "NetworkStream"; }
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
251
src/types/streams/stream.cpp
Normal file
251
src/types/streams/stream.cpp
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
|
||||||
|
#define CROSSLANG_TSTREAM_NAMES \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(getCanRead) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(getCanSeek) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(getCanWrite) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(getEndOfStream) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(getLength) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(getPosition) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(setPosition) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(Close) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(Dispose) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(CopyTo) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(CopyToLimit) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(Flush) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(Read) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(ReadBlock) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(ReadByte) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(Seek) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(SetRecvTimeout) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(SetSendTimeout) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(Write) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(WriteText) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(WriteBlock) \
|
||||||
|
CROSSLANG_TSTREAM_NAME_ENT(WriteByte)
|
||||||
|
|
||||||
|
enum TStreamFuncNameEnum {
|
||||||
|
#define CROSSLANG_TSTREAM_NAME_ENT(name) TSF_##name,
|
||||||
|
CROSSLANG_TSTREAM_NAMES
|
||||||
|
#undef CROSSLANG_TSTREAM_NAME_ENT
|
||||||
|
}; // namespace Tesses::CrossLang
|
||||||
|
|
||||||
|
static std::unordered_map<std::string_view, TStreamFuncNameEnum>
|
||||||
|
stream_func_names = {
|
||||||
|
#define CROSSLANG_TSTREAM_NAME_ENT(name) {#name, TSF_##name},
|
||||||
|
CROSSLANG_TSTREAM_NAMES
|
||||||
|
#undef CROSSLANG_TSTREAM_NAME_ENT
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ITStream::Exists(std::string_view str) {
|
||||||
|
return stream_func_names.count(str) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TObject ITStream::CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args) {
|
||||||
|
|
||||||
|
auto strm = GetStream();
|
||||||
|
if (strm == nullptr)
|
||||||
|
return Undefined();
|
||||||
|
|
||||||
|
auto result = stream_func_names.find(name);
|
||||||
|
|
||||||
|
if (result == stream_func_names.end())
|
||||||
|
return Undefined();
|
||||||
|
|
||||||
|
switch (result->second) {
|
||||||
|
case TSF_getCanRead:
|
||||||
|
return strm->CanRead();
|
||||||
|
case TSF_getCanSeek:
|
||||||
|
return strm->CanSeek();
|
||||||
|
case TSF_getCanWrite:
|
||||||
|
return strm->CanWrite();
|
||||||
|
case TSF_getEndOfStream:
|
||||||
|
return strm->EndOfStream();
|
||||||
|
case TSF_getLength:
|
||||||
|
return strm->GetLength();
|
||||||
|
case TSF_getPosition:
|
||||||
|
return strm->GetPosition();
|
||||||
|
case TSF_setPosition: {
|
||||||
|
int64_t n;
|
||||||
|
if (GetArgument(args, 0, n)) {
|
||||||
|
strm->Seek(n, Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_Close:
|
||||||
|
case TSF_Dispose:
|
||||||
|
strm->Close();
|
||||||
|
return Undefined();
|
||||||
|
case TSF_CopyTo: {
|
||||||
|
ITStream *strmDest;
|
||||||
|
if (GetArgumentHeap(args, 0, strmDest)) {
|
||||||
|
int64_t n = 1024;
|
||||||
|
GetArgument(args, 1, n);
|
||||||
|
strm->CopyTo(strmDest->GetStream(), (size_t)n);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_CopyToLimit: {
|
||||||
|
ITStream *strmDest;
|
||||||
|
int64_t len;
|
||||||
|
if (GetArgumentHeap(args, 0, strmDest) && GetArgument(args, 1, len)) {
|
||||||
|
int64_t n = 1024;
|
||||||
|
GetArgument(args, 2, n);
|
||||||
|
strm->CopyToLimit(strmDest->GetStream(), (uint64_t)len, (size_t)n);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_Flush:
|
||||||
|
strm->Flush();
|
||||||
|
return Undefined();
|
||||||
|
case TSF_Read: {
|
||||||
|
TMutByteView *bytes;
|
||||||
|
if (GetArgumentHeap(args, 0, bytes)) {
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
if (GetArgument(args, 1, offset) && GetArgument(args, 2, length)) {
|
||||||
|
auto safe = bytes->GetMutableBoundsConstrained((size_t)offset,
|
||||||
|
(size_t)length);
|
||||||
|
if (safe.first != nullptr)
|
||||||
|
return strm->Read(safe.first, safe.second);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bounds = bytes->GetMutableBounds();
|
||||||
|
|
||||||
|
if (bounds.first) {
|
||||||
|
return (int64_t)strm->Read(bounds.first, bounds.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_ReadBlock: {
|
||||||
|
TMutByteView *bytes;
|
||||||
|
if (GetArgumentHeap(args, 0, bytes)) {
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
if (GetArgument(args, 1, offset) && GetArgument(args, 2, length)) {
|
||||||
|
auto safe = bytes->GetMutableBoundsConstrained((size_t)offset,
|
||||||
|
(size_t)length);
|
||||||
|
if (safe.first != nullptr)
|
||||||
|
return strm->ReadBlock(safe.first, safe.second);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bounds = bytes->GetMutableBounds();
|
||||||
|
|
||||||
|
if (bounds.first) {
|
||||||
|
return (int64_t)strm->ReadBlock(bounds.first, bounds.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_ReadByte: {
|
||||||
|
return (int64_t)strm->ReadByte();
|
||||||
|
}
|
||||||
|
case TSF_Seek: {
|
||||||
|
int64_t offset;
|
||||||
|
int64_t whence;
|
||||||
|
if (GetArgument(args, 0, offset) && GetArgument(args, 1, whence)) {
|
||||||
|
strm->Seek(offset, (Tesses::Framework::Streams::SeekOrigin)whence);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_SetRecvTimeout: {
|
||||||
|
int64_t to;
|
||||||
|
if (GetArgument(args, 0, to)) {
|
||||||
|
strm->SetRecvTimeout((uint64_t)to);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_SetSendTimeout: {
|
||||||
|
int64_t to;
|
||||||
|
if (GetArgument(args, 0, to)) {
|
||||||
|
strm->SetSendTimeout((uint64_t)to);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_Write: {
|
||||||
|
TByteView *bytes;
|
||||||
|
if (GetArgumentHeap(args, 0, bytes)) {
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
if (GetArgument(args, 1, offset) && GetArgument(args, 2, length)) {
|
||||||
|
auto safe =
|
||||||
|
bytes->GetBoundsConstrained((size_t)offset, (size_t)length);
|
||||||
|
if (safe.first != nullptr)
|
||||||
|
return strm->Write(safe.first, safe.second);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bounds = bytes->GetBounds();
|
||||||
|
|
||||||
|
if (bounds.first) {
|
||||||
|
return (int64_t)strm->Write(bounds.first, bounds.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_WriteText: { // for compat
|
||||||
|
TByteView *bytes;
|
||||||
|
if (GetArgumentHeap(args, 0, bytes)) {
|
||||||
|
auto bounds = bytes->GetBounds();
|
||||||
|
if (bounds.first)
|
||||||
|
strm->WriteBlock(bounds.first, bounds.second);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_WriteBlock: {
|
||||||
|
TByteView *bytes;
|
||||||
|
if (GetArgumentHeap(args, 0, bytes)) {
|
||||||
|
int64_t offset;
|
||||||
|
int64_t length;
|
||||||
|
if (GetArgument(args, 1, offset) && GetArgument(args, 2, length)) {
|
||||||
|
auto safe =
|
||||||
|
bytes->GetBoundsConstrained((size_t)offset, (size_t)length);
|
||||||
|
if (safe.first != nullptr)
|
||||||
|
strm->WriteBlock(safe.first, safe.second);
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bounds = bytes->GetBounds();
|
||||||
|
|
||||||
|
if (bounds.first) {
|
||||||
|
strm->WriteBlock(bounds.first, bounds.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
case TSF_WriteByte: {
|
||||||
|
int64_t b0;
|
||||||
|
if (GetArgument(args, 0, b0)) {
|
||||||
|
strm->WriteByte((uint8_t)b0);
|
||||||
|
}
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
std::string ITStream::TypeName() { return "Stream"; }
|
||||||
|
|
||||||
|
TStream::TStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||||
|
: strm(strm) {}
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> TStream::GetStream() {
|
||||||
|
return this->strm;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
56
src/types/streams/streamwrapper.cpp
Normal file
56
src/types/streams/streamwrapper.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
TObjectStreamWrapper::TObjectStreamWrapper(std::shared_ptr<TObjectStream> strm)
|
||||||
|
: strm(strm) {}
|
||||||
|
TObject TObjectStreamWrapper::CallMethod(InterperterThread *thrd, GCList &ls,
|
||||||
|
const std::string &name,
|
||||||
|
const std::vector<TObject> &args) {
|
||||||
|
if (Exists(name)) {
|
||||||
|
return ITStream::CallMethod(thrd, ls, name, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDictionary *dict;
|
||||||
|
|
||||||
|
if (GetObjectHeap(strm->obj, dict)) {
|
||||||
|
auto val = dict->GetValue(name);
|
||||||
|
|
||||||
|
TCallable *call;
|
||||||
|
if (GetObjectHeap(val, call)) {
|
||||||
|
|
||||||
|
auto closure = dynamic_cast<TClosure *>(call);
|
||||||
|
|
||||||
|
if (closure && !closure->closure->args.empty() &&
|
||||||
|
closure->closure->args[0]->GetString() == "this") {
|
||||||
|
std::vector<TObject> args_new;
|
||||||
|
args_new.reserve(args.size() + 1);
|
||||||
|
args_new.push_back(dict);
|
||||||
|
args_new.insert(args_new.cend(), args.begin(), args.end());
|
||||||
|
|
||||||
|
return closure->Call(ls, args_new);
|
||||||
|
} else {
|
||||||
|
return call->Call(ls, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.size() > 3 && name[1] == 'e' && name[2] == 't') {
|
||||||
|
char c = name[0];
|
||||||
|
if (c == 'g') {
|
||||||
|
auto fieldName = name.substr(3);
|
||||||
|
return dict->GetValue(fieldName);
|
||||||
|
} else if (c == 's' && !args.empty()) {
|
||||||
|
auto fieldName = name.substr(3);
|
||||||
|
dict->SetValue(fieldName, args[0]);
|
||||||
|
ls.Add(args[0]);
|
||||||
|
return args[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream>
|
||||||
|
TObjectStreamWrapper::GetStream() {
|
||||||
|
return this->strm;
|
||||||
|
}
|
||||||
|
std::string TObjectStreamWrapper::TypeName() { return "CustomStream"; }
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -121,6 +121,15 @@ bool InterperterThread::Add(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, str);
|
cse.back()->Push(gc, str);
|
||||||
} else if (std::holds_alternative<THeapObject *>(left)) {
|
} else if (std::holds_alternative<THeapObject *>(left)) {
|
||||||
auto obj = std::get<THeapObject *>(left);
|
auto obj = std::get<THeapObject *>(left);
|
||||||
|
|
||||||
|
if (obj == nullptr) {
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj->opAdd(this, gc, right);
|
||||||
|
|
||||||
|
/*
|
||||||
auto dict = dynamic_cast<TDictionary *>(obj);
|
auto dict = dynamic_cast<TDictionary *>(obj);
|
||||||
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
|
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
|
||||||
auto natObj = dynamic_cast<TNativeObject *>(obj);
|
auto natObj = dynamic_cast<TNativeObject *>(obj);
|
||||||
@@ -156,6 +165,7 @@ bool InterperterThread::Add(std::shared_ptr<GC> gc) {
|
|||||||
} else {
|
} else {
|
||||||
cse.back()->Push(gc, Undefined());
|
cse.back()->Push(gc, Undefined());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cse.back()->Push(gc, Undefined());
|
cse.back()->Push(gc, Undefined());
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
if (GetArgument(args, 0, str)) {
|
if (GetArgument(args, 0, str)) {
|
||||||
std::smatch m;
|
std::smatch m;
|
||||||
if (std::regex_search(str, m, regex)) {
|
if (std::regex_search(str, m, regex)) {
|
||||||
auto myLs = TList::Create(ls);
|
auto myLs = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto item : m) {
|
for (auto item : m) {
|
||||||
auto itm = TDictionary::Create(ls);
|
auto itm = TDictionary::Create(ls);
|
||||||
@@ -288,7 +288,7 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
std::get<Tesses::Framework::Filesystem::VFSPath>(instance);
|
std::get<Tesses::Framework::Filesystem::VFSPath>(instance);
|
||||||
if (key == "GetEnumerator") {
|
if (key == "GetEnumerator") {
|
||||||
|
|
||||||
TList *_ls = TList::Create(ls);
|
TList *_ls = ls.Create<TList>();
|
||||||
for (auto item : path.path) {
|
for (auto item : path.path) {
|
||||||
_ls->Add(item);
|
_ls->Add(item);
|
||||||
}
|
}
|
||||||
@@ -683,7 +683,7 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
|
|
||||||
auto res = Tesses::Framework::Http::HttpUtils::SplitString(
|
auto res = Tesses::Framework::Http::HttpUtils::SplitString(
|
||||||
str, delimiter, count);
|
str, delimiter, count);
|
||||||
TList *mls = TList::Create(ls);
|
TList *mls = ls.Create<TList>();
|
||||||
for (auto item : res) {
|
for (auto item : res) {
|
||||||
if (!removeEmpty || !item.empty())
|
if (!removeEmpty || !item.empty())
|
||||||
mls->Add(item);
|
mls->Add(item);
|
||||||
@@ -825,7 +825,7 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
std::vector<std::string> lines;
|
std::vector<std::string> lines;
|
||||||
textReader->ReadAllLines(lines);
|
textReader->ReadAllLines(lines);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
for (auto &item : lines)
|
for (auto &item : lines)
|
||||||
list->Add(item);
|
list->Add(item);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
@@ -1072,8 +1072,6 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(
|
std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(
|
||||||
instance);
|
instance);
|
||||||
if (strm != nullptr) {
|
if (strm != nullptr) {
|
||||||
auto memStrm = std::dynamic_pointer_cast<
|
|
||||||
Tesses::Framework::Streams::MemoryStream>(strm);
|
|
||||||
auto netStrm = std::dynamic_pointer_cast<
|
auto netStrm = std::dynamic_pointer_cast<
|
||||||
Tesses::Framework::Streams::NetworkStream>(strm);
|
Tesses::Framework::Streams::NetworkStream>(strm);
|
||||||
|
|
||||||
@@ -1090,134 +1088,8 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
return InvokeMethod(ls, o, dict2, args);
|
return InvokeMethod(ls, o, dict2, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (memStrm != nullptr) {
|
|
||||||
if (key == "GetBytes") {
|
|
||||||
auto res = TByteArray::Create(ls);
|
|
||||||
res->data = memStrm->GetBuffer();
|
|
||||||
cse.back()->Push(gc, res);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (netStrm != nullptr) {
|
if (netStrm != nullptr) {
|
||||||
if (key == "SetMulticastMembership") {
|
|
||||||
std::string ma;
|
|
||||||
std::string ifaceIP = "0.0.0.0";
|
|
||||||
if (GetArgument(args, 0, ma)) {
|
|
||||||
GetArgument(args, 1, ifaceIP);
|
|
||||||
netStrm->SetMulticastMembership(ma, ifaceIP);
|
|
||||||
}
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "GetPort") {
|
|
||||||
cse.back()->Push(gc, (int64_t)netStrm->GetPort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "Bind") {
|
|
||||||
std::string ip;
|
|
||||||
int64_t port;
|
|
||||||
if (GetArgument(args, 0, ip) &&
|
|
||||||
GetArgument(args, 1, port))
|
|
||||||
netStrm->Bind(ip, (uint16_t)port);
|
|
||||||
|
|
||||||
cse.back()->Push(gc, nullptr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "Accept") {
|
|
||||||
std::string ip;
|
|
||||||
uint16_t port;
|
|
||||||
auto strm = netStrm->Accept(ip, port);
|
|
||||||
TDictionary *dict = TDictionary::Create(ls);
|
|
||||||
gc->BarrierBegin();
|
|
||||||
dict->SetValue("IP", ip);
|
|
||||||
dict->SetValue("Port", (int64_t)port);
|
|
||||||
dict->SetValue("Stream", strm);
|
|
||||||
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, dict);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "Listen") {
|
|
||||||
int64_t backlog;
|
|
||||||
if (GetArgument(args, 0, backlog)) {
|
|
||||||
netStrm->Listen((int32_t)backlog);
|
|
||||||
} else {
|
|
||||||
netStrm->Listen(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
cse.back()->Push(gc, nullptr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "ReadFrom") {
|
|
||||||
TByteArray *data;
|
|
||||||
int64_t offset;
|
|
||||||
int64_t length;
|
|
||||||
if (GetArgumentHeap<TByteArray *>(args, 0, data) &&
|
|
||||||
GetArgument<int64_t>(args, 1, offset) &&
|
|
||||||
GetArgument<int64_t>(args, 2, length)) {
|
|
||||||
size_t off = (size_t)offset;
|
|
||||||
size_t len = (size_t)length;
|
|
||||||
std::string ip = {};
|
|
||||||
uint16_t port = 0;
|
|
||||||
|
|
||||||
if (off < len)
|
|
||||||
|
|
||||||
len = netStrm->ReadFrom(
|
|
||||||
data->data.data() + off,
|
|
||||||
std::min(len,
|
|
||||||
std::min(data->data.size() - off,
|
|
||||||
data->data.size())),
|
|
||||||
ip, port);
|
|
||||||
|
|
||||||
else
|
|
||||||
len = 0;
|
|
||||||
|
|
||||||
TDictionary *dict = TDictionary::Create(ls);
|
|
||||||
gc->BarrierBegin();
|
|
||||||
dict->SetValue("IP", ip);
|
|
||||||
dict->SetValue("Port", (int64_t)port);
|
|
||||||
dict->SetValue("Read", (int64_t)len);
|
|
||||||
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, dict);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cse.back()->Push(gc, nullptr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "WriteTo") {
|
|
||||||
TByteArray *data;
|
|
||||||
int64_t offset;
|
|
||||||
int64_t length;
|
|
||||||
std::string ip;
|
|
||||||
int64_t port;
|
|
||||||
if (GetArgumentHeap<TByteArray *>(args, 0, data) &&
|
|
||||||
GetArgument<int64_t>(args, 1, offset) &&
|
|
||||||
GetArgument<int64_t>(args, 2, length) &&
|
|
||||||
GetArgument(args, 3, ip) &&
|
|
||||||
GetArgument(args, 4, port)) {
|
|
||||||
size_t off = (size_t)offset;
|
|
||||||
size_t len = (size_t)length;
|
|
||||||
|
|
||||||
if (off < len)
|
|
||||||
|
|
||||||
len = netStrm->WriteTo(
|
|
||||||
data->data.data() + off,
|
|
||||||
std::min(len,
|
|
||||||
std::min(data->data.size() - off,
|
|
||||||
data->data.size())),
|
|
||||||
ip, (int64_t)port);
|
|
||||||
|
|
||||||
else
|
|
||||||
len = 0;
|
|
||||||
|
|
||||||
cse.back()->Push(gc, (int64_t)len);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cse.back()->Push(gc, nullptr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == "Read") {
|
if (key == "Read") {
|
||||||
@@ -1966,7 +1838,7 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
return false;
|
return false;
|
||||||
} else if (std::holds_alternative<THeapObject *>(instance)) {
|
} else if (std::holds_alternative<THeapObject *>(instance)) {
|
||||||
auto obj = std::get<THeapObject *>(instance);
|
auto obj = std::get<THeapObject *>(instance);
|
||||||
auto list = dynamic_cast<TList *>(obj);
|
|
||||||
auto dynList = dynamic_cast<TDynamicList *>(obj);
|
auto dynList = dynamic_cast<TDynamicList *>(obj);
|
||||||
auto bArray = dynamic_cast<TByteArray *>(obj);
|
auto bArray = dynamic_cast<TByteArray *>(obj);
|
||||||
auto dict = dynamic_cast<TDictionary *>(obj);
|
auto dict = dynamic_cast<TDictionary *>(obj);
|
||||||
@@ -3336,190 +3208,6 @@ bool InterperterThread::ExecuteMethod2(std::shared_ptr<GC> gc, TObject instance,
|
|||||||
}
|
}
|
||||||
cse.back()->Push(gc, Undefined());
|
cse.back()->Push(gc, Undefined());
|
||||||
return false;
|
return false;
|
||||||
} else if (list != nullptr) {
|
|
||||||
|
|
||||||
if (key == "GetEnumerator") {
|
|
||||||
cse.back()->Push(gc, TListEnumerator::Create(ls, list));
|
|
||||||
return false;
|
|
||||||
} else if (key == "ToString") {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, Json_Encode(list));
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else if (key == "Insert") {
|
|
||||||
if (args.size() != 2) {
|
|
||||||
throw VMException(
|
|
||||||
"List.Insert must only accept two arguments");
|
|
||||||
}
|
|
||||||
int64_t index;
|
|
||||||
|
|
||||||
if (!GetArgument(args, 0, index)) {
|
|
||||||
throw VMException(
|
|
||||||
"List.Insert first argument must be Long");
|
|
||||||
}
|
|
||||||
|
|
||||||
gc->BarrierBegin();
|
|
||||||
list->Insert(index, args[1]);
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
} else if (key == "Add") {
|
|
||||||
if (args.size() != 1) {
|
|
||||||
throw VMException(
|
|
||||||
"List.Add must only accept one argument");
|
|
||||||
}
|
|
||||||
gc->BarrierBegin();
|
|
||||||
list->Add(args[0]);
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
} else if (key == "Contains") {
|
|
||||||
if (args.size() != 1) {
|
|
||||||
throw VMException(
|
|
||||||
"List.Contains must only accept one argument");
|
|
||||||
}
|
|
||||||
gc->BarrierBegin();
|
|
||||||
for (int64_t i = 0; i < list->Count(); i++) {
|
|
||||||
auto item = list->Get(i);
|
|
||||||
gc->BarrierEnd();
|
|
||||||
if (Equals(gc, args[0], item)) {
|
|
||||||
cse.back()->Push(gc, true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
gc->BarrierBegin();
|
|
||||||
}
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, false);
|
|
||||||
return false;
|
|
||||||
} else if (key == "IndexOf") {
|
|
||||||
// IndexOf(obj, $idx)
|
|
||||||
if (args.size() < 1 || args.size() > 2) {
|
|
||||||
throw VMException("List.IndexOf must either have one "
|
|
||||||
"or two arguments");
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t i = 0;
|
|
||||||
|
|
||||||
GetArgument(args, 1, i);
|
|
||||||
gc->BarrierBegin();
|
|
||||||
for (; i < list->Count(); i++) {
|
|
||||||
auto item = list->Get(i);
|
|
||||||
gc->BarrierEnd();
|
|
||||||
if (Equals(gc, args[0], item)) {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, i);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
gc->BarrierBegin();
|
|
||||||
}
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, (int64_t)-1);
|
|
||||||
return false;
|
|
||||||
} else if (key == "RemoveAllEqual") {
|
|
||||||
if (args.size() != 1) {
|
|
||||||
throw VMException("List.RemoveAllEqual must only "
|
|
||||||
"accept one argument");
|
|
||||||
}
|
|
||||||
|
|
||||||
gc->BarrierBegin();
|
|
||||||
for (int64_t i = 0; i < list->Count(); i++) {
|
|
||||||
auto item = list->Get(i);
|
|
||||||
gc->BarrierEnd();
|
|
||||||
if (Equals(gc, args[0], item)) {
|
|
||||||
gc->BarrierBegin();
|
|
||||||
list->RemoveAt(i);
|
|
||||||
i--;
|
|
||||||
} else
|
|
||||||
gc->BarrierBegin();
|
|
||||||
}
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
} else if (key == "Remove") {
|
|
||||||
if (args.size() != 1) {
|
|
||||||
throw VMException(
|
|
||||||
"List.Remove must only accept one argument");
|
|
||||||
}
|
|
||||||
|
|
||||||
gc->BarrierBegin();
|
|
||||||
for (int64_t i = 0; i < list->Count(); i++) {
|
|
||||||
auto item = list->Get(i);
|
|
||||||
gc->BarrierEnd();
|
|
||||||
if (Equals(gc, args[0], item)) {
|
|
||||||
gc->BarrierBegin();
|
|
||||||
list->RemoveAt(i);
|
|
||||||
gc->BarrierEnd();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gc->BarrierBegin();
|
|
||||||
}
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
} else if (key == "RemoveAt") {
|
|
||||||
if (args.size() != 1) {
|
|
||||||
throw VMException(
|
|
||||||
"List.RemoveAt must only accept one argument");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!std::holds_alternative<int64_t>(args[0])) {
|
|
||||||
throw VMException(
|
|
||||||
"List.RemoveAt must only accept a long");
|
|
||||||
}
|
|
||||||
gc->BarrierBegin();
|
|
||||||
list->RemoveAt(std::get<int64_t>(args[0]));
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
} else if (key == "Clear") {
|
|
||||||
gc->BarrierBegin();
|
|
||||||
list->Clear();
|
|
||||||
gc->BarrierEnd();
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
} else if (key == "GetAt") {
|
|
||||||
if (args.size() != 1) {
|
|
||||||
throw VMException(
|
|
||||||
"List.GetAt must only accept one argument");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!std::holds_alternative<int64_t>(args[0])) {
|
|
||||||
throw VMException("List.GetAt must only accept a long");
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t index = std::get<int64_t>(args[0]);
|
|
||||||
if (index >= 0 && index < list->Count()) {
|
|
||||||
cse.back()->Push(gc, list->Get(index));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (key == "SetAt") {
|
|
||||||
if (args.size() != 2) {
|
|
||||||
throw VMException(
|
|
||||||
"List.SetAt must only accept two arguments");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!std::holds_alternative<int64_t>(args[0])) {
|
|
||||||
throw VMException("List.SetAt first argument must only "
|
|
||||||
"accept a long");
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t index = std::get<int64_t>(args[0]);
|
|
||||||
if (index >= 0 && index < list->Count()) {
|
|
||||||
list->Set(index, args[1]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == "Count" || key == "Length") {
|
|
||||||
gc->BarrierBegin();
|
|
||||||
cse.back()->Push(gc, list->Count());
|
|
||||||
gc->BarrierEnd();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
} else if (dynList != nullptr) {
|
} else if (dynList != nullptr) {
|
||||||
|
|
||||||
if (key == "GetEnumerator") {
|
if (key == "GetEnumerator") {
|
||||||
|
|||||||
@@ -145,59 +145,6 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, Undefined());
|
cse.back()->Push(gc, Undefined());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (std::holds_alternative<
|
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream>>(
|
|
||||||
instance)) {
|
|
||||||
auto strm =
|
|
||||||
std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(
|
|
||||||
instance);
|
|
||||||
if (strm != nullptr) {
|
|
||||||
auto netStrm = std::dynamic_pointer_cast<
|
|
||||||
Tesses::Framework::Streams::NetworkStream>(strm);
|
|
||||||
|
|
||||||
if (key == "CanRead") {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, strm->CanRead());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "CanWrite") {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, strm->CanWrite());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "CanSeek") {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, strm->CanSeek());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "EndOfStream") {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, strm->EndOfStream());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "Length") {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, strm->GetLength());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (key == "Position") {
|
|
||||||
|
|
||||||
cse.back()->Push(gc, strm->GetPosition());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netStrm != nullptr) {
|
|
||||||
if (key == "Port") {
|
|
||||||
cse.back()->Push(gc, (int64_t)netStrm->GetPort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cse.back()->Push(gc, Undefined());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::holds_alternative<TVMVersion>(instance)) {
|
if (std::holds_alternative<TVMVersion>(instance)) {
|
||||||
TVMVersion &version = std::get<TVMVersion>(instance);
|
TVMVersion &version = std::get<TVMVersion>(instance);
|
||||||
if (key == "Major") {
|
if (key == "Major") {
|
||||||
@@ -391,7 +338,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, file->info);
|
cse.back()->Push(gc, file->info);
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Dependencies") {
|
} else if (key == "Dependencies") {
|
||||||
auto list = TList::Create(ls);
|
auto list = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto item : file->dependencies) {
|
for (auto item : file->dependencies) {
|
||||||
auto res = TDictionary::Create(ls);
|
auto res = TDictionary::Create(ls);
|
||||||
@@ -403,7 +350,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, list);
|
cse.back()->Push(gc, list);
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Tools") {
|
} else if (key == "Tools") {
|
||||||
auto list = TList::Create(ls);
|
auto list = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto item : file->tools) {
|
for (auto item : file->tools) {
|
||||||
auto res = TDictionary::Create(ls);
|
auto res = TDictionary::Create(ls);
|
||||||
@@ -415,7 +362,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, list);
|
cse.back()->Push(gc, list);
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Strings") {
|
} else if (key == "Strings") {
|
||||||
auto list = TList::Create(ls);
|
auto list = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto item : file->name) {
|
for (auto item : file->name) {
|
||||||
list->Add(item);
|
list->Add(item);
|
||||||
@@ -429,7 +376,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, (int64_t)file->metadata.size());
|
cse.back()->Push(gc, (int64_t)file->metadata.size());
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Metadata") {
|
} else if (key == "Metadata") {
|
||||||
TList *meta = TList::Create(ls);
|
TList *meta = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (size_t i = 0; i < file->metadata.size(); i++) {
|
for (size_t i = 0; i < file->metadata.size(); i++) {
|
||||||
meta->Add(TDictionary::Create(
|
meta->Add(TDictionary::Create(
|
||||||
@@ -441,7 +388,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, meta);
|
cse.back()->Push(gc, meta);
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Sections") {
|
} else if (key == "Sections") {
|
||||||
TList *sections = TList::Create(ls);
|
TList *sections = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto &item : file->sections) {
|
for (auto &item : file->sections) {
|
||||||
TByteArray *ba = TByteArray::Create(ls);
|
TByteArray *ba = TByteArray::Create(ls);
|
||||||
@@ -455,7 +402,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, sections);
|
cse.back()->Push(gc, sections);
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "SupportedVMs") {
|
} else if (key == "SupportedVMs") {
|
||||||
TList *supported = TList::Create(ls);
|
TList *supported = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
if (file->vms.empty()) {
|
if (file->vms.empty()) {
|
||||||
supported->Add(TDictionary::Create(
|
supported->Add(TDictionary::Create(
|
||||||
@@ -471,7 +418,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, supported);
|
cse.back()->Push(gc, supported);
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Chunks") {
|
} else if (key == "Chunks") {
|
||||||
auto list = TList::Create(ls);
|
auto list = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto item : file->chunks) {
|
for (auto item : file->chunks) {
|
||||||
list->Add(item);
|
list->Add(item);
|
||||||
@@ -482,7 +429,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
cse.back()->Push(gc, list);
|
cse.back()->Push(gc, list);
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Classes") {
|
} else if (key == "Classes") {
|
||||||
auto list = TList::Create(ls);
|
auto list = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < (uint32_t)file->classes.size();
|
for (uint32_t i = 0; i < (uint32_t)file->classes.size();
|
||||||
@@ -494,13 +441,13 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return false;
|
return false;
|
||||||
} else if (key == "Functions") {
|
} else if (key == "Functions") {
|
||||||
auto list = TList::Create(ls);
|
auto list = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto &item : file->functions) {
|
for (auto &item : file->functions) {
|
||||||
TDictionary *dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
if (!item.first.empty())
|
if (!item.first.empty())
|
||||||
dict->SetValue("Documentation", item.first[0]);
|
dict->SetValue("Documentation", item.first[0]);
|
||||||
TList *nameParts = TList::Create(ls);
|
TList *nameParts = ls.Create<TList>();
|
||||||
for (size_t i = 1; i < item.first.size(); i++) {
|
for (size_t i = 1; i < item.first.size(); i++) {
|
||||||
nameParts->Add(item.first[i]);
|
nameParts->Add(item.first[i]);
|
||||||
}
|
}
|
||||||
@@ -530,7 +477,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
}
|
}
|
||||||
if (chunk != nullptr) {
|
if (chunk != nullptr) {
|
||||||
if (key == "Arguments") {
|
if (key == "Arguments") {
|
||||||
auto myargs = TList::Create(ls);
|
auto myargs = ls.Create<TList>();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for (auto item : chunk->args) {
|
for (auto item : chunk->args) {
|
||||||
myargs->Add(item);
|
myargs->Add(item);
|
||||||
@@ -586,7 +533,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
if (closure != nullptr) {
|
if (closure != nullptr) {
|
||||||
if (key == "Arguments") {
|
if (key == "Arguments") {
|
||||||
GCList ls2(gc);
|
GCList ls2(gc);
|
||||||
TList *ls = TList::Create(ls2);
|
TList *ls = ls2.Create<TList>();
|
||||||
for (auto arg : closure->closure->args) {
|
for (auto arg : closure->closure->args) {
|
||||||
ls->Add(arg);
|
ls->Add(arg);
|
||||||
}
|
}
|
||||||
@@ -601,7 +548,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
if (externalMethod != nullptr) {
|
if (externalMethod != nullptr) {
|
||||||
if (key == "Arguments") {
|
if (key == "Arguments") {
|
||||||
GCList ls2(gc);
|
GCList ls2(gc);
|
||||||
TList *ls = TList::Create(ls2);
|
TList *ls = ls2.Create<TList>();
|
||||||
for (auto arg : externalMethod->args) {
|
for (auto arg : externalMethod->args) {
|
||||||
ls->Add(arg);
|
ls->Add(arg);
|
||||||
}
|
}
|
||||||
@@ -635,16 +582,7 @@ bool InterperterThread::GetField(std::shared_ptr<GC> gc) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list != nullptr) {
|
|
||||||
if (key == "Count" || key == "Length") {
|
|
||||||
int64_t len = list->Count();
|
|
||||||
if (len < 0)
|
|
||||||
len = 0;
|
|
||||||
|
|
||||||
stk->Push(gc, len);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dynList != nullptr) {
|
if (dynList != nullptr) {
|
||||||
if (key == "Count" || key == "Length") {
|
if (key == "Count" || key == "Length") {
|
||||||
int64_t len = dynList->Count(ls);
|
int64_t len = dynList->Count(ls);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ bool InterperterThread::InvokeMethod(GCList &ls, TObject fn, TObject instance,
|
|||||||
if (closure != nullptr) {
|
if (closure != nullptr) {
|
||||||
|
|
||||||
if (!closure->closure->args.empty() &&
|
if (!closure->closure->args.empty() &&
|
||||||
closure->closure->args[0] == "this") {
|
closure->closure->args[0].GetString() == "this") {
|
||||||
std::vector<TObject> args2;
|
std::vector<TObject> args2;
|
||||||
args2.push_back(instance);
|
args2.push_back(instance);
|
||||||
args2.insert(args2.end(), args.begin(), args.end());
|
args2.insert(args2.end(), args.begin(), args.end());
|
||||||
|
|||||||
@@ -231,32 +231,7 @@ bool InterperterThread::SetField(std::shared_ptr<GC> gc) {
|
|||||||
stk->Push(gc, Undefined());
|
stk->Push(gc, Undefined());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (std::holds_alternative<
|
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream>>(
|
|
||||||
instance)) {
|
|
||||||
auto strm =
|
|
||||||
std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(
|
|
||||||
instance);
|
|
||||||
|
|
||||||
auto netStrm = std::dynamic_pointer_cast<
|
|
||||||
Tesses::Framework::Streams::NetworkStream>(strm);
|
|
||||||
if (netStrm != nullptr) {
|
|
||||||
int64_t n0;
|
|
||||||
bool bc;
|
|
||||||
if (key == "Broadcast" && GetObject(value, bc))
|
|
||||||
netStrm->SetBroadcast(bc);
|
|
||||||
if (key == "NoDelay" && GetObject(value, bc))
|
|
||||||
netStrm->SetNoDelay(bc);
|
|
||||||
if (key == "ReuseAddress" && GetObject(value, bc))
|
|
||||||
netStrm->SetReuseAddress(bc);
|
|
||||||
if (key == "ReusePort" && GetObject(value, bc))
|
|
||||||
netStrm->SetReusePort(bc);
|
|
||||||
if (key == "MulticastTTL" && GetObject(value, n0))
|
|
||||||
netStrm->SetMulticastTTL((uint8_t)n0);
|
|
||||||
}
|
|
||||||
stk->Push(gc, Undefined());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (std::holds_alternative<THeapObject *>(instance)) {
|
if (std::holds_alternative<THeapObject *>(instance)) {
|
||||||
auto obj = std::get<THeapObject *>(instance);
|
auto obj = std::get<THeapObject *>(instance);
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,15 @@ bool InterperterThread::Sub(std::shared_ptr<GC> gc) {
|
|||||||
std::make_shared<Tesses::Framework::Date::DateTime>((*l) - (*r)));
|
std::make_shared<Tesses::Framework::Date::DateTime>((*l) - (*r)));
|
||||||
} else if (std::holds_alternative<THeapObject *>(left)) {
|
} else if (std::holds_alternative<THeapObject *>(left)) {
|
||||||
auto obj = std::get<THeapObject *>(left);
|
auto obj = std::get<THeapObject *>(left);
|
||||||
auto dict = dynamic_cast<TDictionary *>(obj);
|
|
||||||
|
if (obj == nullptr) {
|
||||||
|
cse.back()->Push(gc, Undefined());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj->opSub(this, gc, right);
|
||||||
|
|
||||||
|
/*auto dict = dynamic_cast<TDictionary *>(obj);
|
||||||
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
|
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
|
||||||
|
|
||||||
auto natObj = dynamic_cast<TNativeObject *>(obj);
|
auto natObj = dynamic_cast<TNativeObject *>(obj);
|
||||||
@@ -104,7 +112,7 @@ bool InterperterThread::Sub(std::shared_ptr<GC> gc) {
|
|||||||
} else {
|
} else {
|
||||||
cse.back()->Push(gc, Undefined());
|
cse.back()->Push(gc, Undefined());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
cse.back()->Push(gc, Undefined());
|
cse.back()->Push(gc, Undefined());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,15 +43,18 @@ void TFile::Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> stream,
|
|||||||
"End of file, could not read " + std::to_string((int64_t)len) +
|
"End of file, could not read " + std::to_string((int64_t)len) +
|
||||||
" byte(s)., offset=" + std::to_string(stream->GetLength()));
|
" byte(s)., offset=" + std::to_string(stream->GetLength()));
|
||||||
}
|
}
|
||||||
std::string TFile::EnsureString(
|
void TFile::EnsureString(
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
|
GCList &ls, std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
|
||||||
auto len = EnsureInt(stream);
|
auto len = EnsureInt(stream);
|
||||||
if (len == 0)
|
if (len == 0) {
|
||||||
return {};
|
this->strings.push_back(ls.FromString(""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::string str = {};
|
std::string str = {};
|
||||||
str.resize((size_t)len);
|
str.resize((size_t)len);
|
||||||
Ensure(stream, (uint8_t *)str.data(), str.size());
|
Ensure(stream, (uint8_t *)str.data(), str.size());
|
||||||
return str;
|
|
||||||
|
this->strings.push_back(ls.Create<TString>(std::move(str)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
@@ -60,7 +63,7 @@ TFile::EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
|
|||||||
Ensure(stream, buffer, 4);
|
Ensure(stream, buffer, 4);
|
||||||
return BitConverter::ToUint32BE(buffer[0]);
|
return BitConverter::ToUint32BE(buffer[0]);
|
||||||
}
|
}
|
||||||
std::string
|
TString *
|
||||||
TFile::GetString(std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
|
TFile::GetString(std::shared_ptr<Tesses::Framework::Streams::Stream> stream) {
|
||||||
uint32_t index = EnsureInt(stream);
|
uint32_t index = EnsureInt(stream);
|
||||||
if (index >= this->strings.size())
|
if (index >= this->strings.size())
|
||||||
@@ -75,7 +78,7 @@ void TFile::EnsureCanRunInCrossLang() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto item : this->vms) {
|
for (auto item : this->vms) {
|
||||||
if (item.first == VMName) {
|
if (item.first->GetString() == VMName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +86,8 @@ void TFile::EnsureCanRunInCrossLang() {
|
|||||||
std::string errorMessage = "The virtual machines supported are:\n";
|
std::string errorMessage = "The virtual machines supported are:\n";
|
||||||
|
|
||||||
for (auto item : this->vms) {
|
for (auto item : this->vms) {
|
||||||
errorMessage += item.first + "\n\t" + item.second + "\n";
|
errorMessage +=
|
||||||
|
item.first->GetString() + "\n\t" + item.second->GetString() + "\n";
|
||||||
}
|
}
|
||||||
throw VMException(errorMessage);
|
throw VMException(errorMessage);
|
||||||
}
|
}
|
||||||
@@ -152,7 +156,7 @@ TDictionary *TFile::MetadataDecode(GCList &ls, size_t midx) {
|
|||||||
items.push_back(parseEnt());
|
items.push_back(parseEnt());
|
||||||
}
|
}
|
||||||
|
|
||||||
return TList::Create(ls, items.begin(), items.end());
|
return ls.Create<TList>(items.begin(), items.end());
|
||||||
} else
|
} else
|
||||||
throw std::out_of_range("Abrupt end of metadata");
|
throw std::out_of_range("Abrupt end of metadata");
|
||||||
} break;
|
} break;
|
||||||
@@ -166,8 +170,8 @@ TDictionary *TFile::MetadataDecode(GCList &ls, size_t midx) {
|
|||||||
if (index + 4 <= bytes.size()) {
|
if (index + 4 <= bytes.size()) {
|
||||||
auto val2 = BitConverter::ToUint32BE(bytes[index]);
|
auto val2 = BitConverter::ToUint32BE(bytes[index]);
|
||||||
index += 4;
|
index += 4;
|
||||||
std::string &text = this->strings.at((size_t)val2);
|
TString *text = this->strings.at((size_t)val2);
|
||||||
items.emplace_back(text, parseEnt());
|
items.emplace_back(text->GetString(), parseEnt());
|
||||||
} else
|
} else
|
||||||
throw std::out_of_range("Abrupt end of metadata");
|
throw std::out_of_range("Abrupt end of metadata");
|
||||||
}
|
}
|
||||||
@@ -180,9 +184,7 @@ TDictionary *TFile::MetadataDecode(GCList &ls, size_t midx) {
|
|||||||
if (index + 4 <= bytes.size()) {
|
if (index + 4 <= bytes.size()) {
|
||||||
auto val = BitConverter::ToUint32BE(bytes[index]);
|
auto val = BitConverter::ToUint32BE(bytes[index]);
|
||||||
index += 4;
|
index += 4;
|
||||||
auto ba = TByteArray::Create(ls);
|
return ls.Create<TByteArray>(this->resources.at((size_t)val));
|
||||||
ba->data = this->resources.at((size_t)val);
|
|
||||||
return ba;
|
|
||||||
} else
|
} else
|
||||||
throw std::out_of_range("Abrupt end of metadata");
|
throw std::out_of_range("Abrupt end of metadata");
|
||||||
} break;
|
} break;
|
||||||
@@ -190,7 +192,8 @@ TDictionary *TFile::MetadataDecode(GCList &ls, size_t midx) {
|
|||||||
if (index + 4 <= bytes.size()) {
|
if (index + 4 <= bytes.size()) {
|
||||||
auto val = BitConverter::ToUint32BE(bytes[index]);
|
auto val = BitConverter::ToUint32BE(bytes[index]);
|
||||||
index += 4;
|
index += 4;
|
||||||
return std::make_shared<EmbedStream>(ls.GetGC(), this, val);
|
return ls.Create<TStream>(
|
||||||
|
std::make_shared<EmbedStream>(ls.GetGC(), this, val));
|
||||||
} else
|
} else
|
||||||
throw std::out_of_range("Abrupt end of metadata");
|
throw std::out_of_range("Abrupt end of metadata");
|
||||||
} break;
|
} break;
|
||||||
@@ -212,8 +215,8 @@ TDictionary *TFile::MetadataDecode(GCList &ls, size_t midx) {
|
|||||||
ls, "", {},
|
ls, "", {},
|
||||||
[val, this](GCList &ls,
|
[val, this](GCList &ls,
|
||||||
std::vector<TObject> args) -> TObject {
|
std::vector<TObject> args) -> TObject {
|
||||||
return std::make_shared<EmbedStream>(ls.GetGC(), this,
|
return ls.Create<TStream>(std::make_shared<EmbedStream>(
|
||||||
val);
|
ls.GetGC(), this, val));
|
||||||
});
|
});
|
||||||
em->watch.push_back(this);
|
em->watch.push_back(this);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
@@ -261,26 +264,36 @@ void TFile::Load(std::shared_ptr<GC> gc,
|
|||||||
this->info = GetString(stream);
|
this->info = GetString(stream);
|
||||||
} else if (strncmp(table_name, "DEPS", 4) == 0) // dependencies
|
} else if (strncmp(table_name, "DEPS", 4) == 0) // dependencies
|
||||||
{
|
{
|
||||||
std::string name = GetString(stream);
|
TString *name = GetString(stream);
|
||||||
uint8_t version_bytes[5];
|
uint8_t version_bytes[5];
|
||||||
Ensure(stream, version_bytes, sizeof(version_bytes));
|
Ensure(stream, version_bytes, sizeof(version_bytes));
|
||||||
TVMVersion depVersion(version_bytes);
|
TVMVersion depVersion(version_bytes);
|
||||||
|
gc->BarrierBegin();
|
||||||
this->dependencies.push_back(
|
this->dependencies.push_back(
|
||||||
std::pair<std::string, TVMVersion>(name, depVersion));
|
std::pair<TString *, TVMVersion>(name, depVersion));
|
||||||
|
gc->BarrierEnd();
|
||||||
} else if (strncmp(table_name, "TOOL", 4) ==
|
} else if (strncmp(table_name, "TOOL", 4) ==
|
||||||
0) // compile tools (for package manager)
|
0) // compile tools (for package manager)
|
||||||
{
|
{
|
||||||
std::string name = GetString(stream);
|
TString *name = GetString(stream);
|
||||||
uint8_t version_bytes[5];
|
uint8_t version_bytes[5];
|
||||||
Ensure(stream, version_bytes, sizeof(version_bytes));
|
Ensure(stream, version_bytes, sizeof(version_bytes));
|
||||||
TVMVersion depVersion(version_bytes);
|
TVMVersion depVersion(version_bytes);
|
||||||
|
gc->BarrierBegin();
|
||||||
this->tools.push_back(
|
this->tools.push_back(
|
||||||
std::pair<std::string, TVMVersion>(name, depVersion));
|
std::pair<TString *, TVMVersion>(name, depVersion));
|
||||||
|
gc->BarrierEnd();
|
||||||
} else if (strncmp(table_name, "RESO", 4) ==
|
} else if (strncmp(table_name, "RESO", 4) ==
|
||||||
0) // resources (using embed)
|
0) // resources (using embed)
|
||||||
{
|
{
|
||||||
auto &data = this->resources.emplace_back(tableLen);
|
std::vector<uint8_t> data;
|
||||||
|
data.resize(tableLen);
|
||||||
Ensure(stream, data.data(), data.size());
|
Ensure(stream, data.data(), data.size());
|
||||||
|
GCList ls(gc);
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->resources.push_back(ls.Create<TResource>(std::move(data)));
|
||||||
|
gc->BarrierEnd();
|
||||||
|
|
||||||
} else if (strncmp(table_name, "CHKS", 4) == 0 &&
|
} else if (strncmp(table_name, "CHKS", 4) == 0 &&
|
||||||
gc != nullptr) // chunks
|
gc != nullptr) // chunks
|
||||||
{
|
{
|
||||||
@@ -288,11 +301,13 @@ void TFile::Load(std::shared_ptr<GC> gc,
|
|||||||
size_t chunkCount = (size_t)EnsureInt(stream);
|
size_t chunkCount = (size_t)EnsureInt(stream);
|
||||||
for (size_t j = 0; j < chunkCount; j++) {
|
for (size_t j = 0; j < chunkCount; j++) {
|
||||||
|
|
||||||
auto chunk = TFileChunk::Create(ls);
|
auto chunk = ls.Create<TFileChunk>();
|
||||||
chunk->file = this;
|
chunk->file = this;
|
||||||
size_t argCount = (size_t)EnsureInt(stream);
|
size_t argCount = (size_t)EnsureInt(stream);
|
||||||
for (size_t k = 0; k < argCount; k++) {
|
for (size_t k = 0; k < argCount; k++) {
|
||||||
|
gc->BarrierBegin();
|
||||||
chunk->args.push_back(GetString(stream));
|
chunk->args.push_back(GetString(stream));
|
||||||
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
size_t len = (size_t)EnsureInt(stream);
|
size_t len = (size_t)EnsureInt(stream);
|
||||||
chunk->code.resize(len);
|
chunk->code.resize(len);
|
||||||
@@ -307,33 +322,45 @@ void TFile::Load(std::shared_ptr<GC> gc,
|
|||||||
size_t funLength = (size_t)EnsureInt(stream);
|
size_t funLength = (size_t)EnsureInt(stream);
|
||||||
|
|
||||||
for (size_t j = 0; j < funLength; j++) {
|
for (size_t j = 0; j < funLength; j++) {
|
||||||
std::vector<std::string> fnParts;
|
std::vector<TString *> fnParts;
|
||||||
uint32_t fnPartsC = EnsureInt(stream);
|
uint32_t fnPartsC = EnsureInt(stream);
|
||||||
for (uint32_t k = 0; k < fnPartsC; k++) {
|
for (uint32_t k = 0; k < fnPartsC; k++) {
|
||||||
fnParts.push_back(GetString(stream));
|
fnParts.push_back(GetString(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fnNumber = EnsureInt(stream);
|
uint32_t fnNumber = EnsureInt(stream);
|
||||||
|
gc->BarrierBegin();
|
||||||
this->functions.push_back(
|
this->functions.push_back(
|
||||||
std::pair<std::vector<std::string>, uint32_t>(fnParts,
|
std::pair<std::vector<TString *>, uint32_t>(fnParts,
|
||||||
fnNumber));
|
fnNumber));
|
||||||
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (strncmp(table_name, "STRS", 4) == 0) // strings
|
} else if (strncmp(table_name, "STRS", 4) == 0) // strings
|
||||||
{
|
{
|
||||||
size_t strsLen = (size_t)EnsureInt(stream);
|
size_t strsLen = (size_t)EnsureInt(stream);
|
||||||
|
|
||||||
|
gc->BarrierBegin();
|
||||||
|
this->strings.reserve(strsLen);
|
||||||
|
gc->BarrierEnd();
|
||||||
|
|
||||||
|
GCList ls(gc);
|
||||||
for (size_t j = 0; j < strsLen; j++) {
|
for (size_t j = 0; j < strsLen; j++) {
|
||||||
this->strings.push_back(EnsureString(stream));
|
gc->BarrierBegin();
|
||||||
|
EnsureString(ls, stream);
|
||||||
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
} else if (strncmp(table_name, "ICON", 4) == 0) // icon
|
} else if (strncmp(table_name, "ICON", 4) == 0) // icon
|
||||||
{
|
{
|
||||||
this->icon = (int32_t)EnsureInt(stream);
|
this->icon = this->resources.at(EnsureInt(stream));
|
||||||
} else if (strncmp(table_name, "MACH", 4) == 0) // machine
|
} else if (strncmp(table_name, "MACH", 4) == 0) // machine
|
||||||
{
|
{
|
||||||
std::string name = GetString(stream);
|
TString *name = GetString(stream);
|
||||||
std::string howToGet = GetString(stream);
|
TString *howToGet = GetString(stream);
|
||||||
|
gc->BarrierBegin();
|
||||||
this->vms.push_back(
|
this->vms.push_back(
|
||||||
std::pair<std::string, std::string>(name, howToGet));
|
std::pair<TString *, TString *>(name, howToGet));
|
||||||
|
gc->BarrierEnd();
|
||||||
} else if (strncmp(table_name, "CLSS", 4) == 0) // classes
|
} else if (strncmp(table_name, "CLSS", 4) == 0) // classes
|
||||||
{
|
{
|
||||||
uint32_t clsCnt = EnsureInt(stream);
|
uint32_t clsCnt = EnsureInt(stream);
|
||||||
@@ -341,14 +368,17 @@ void TFile::Load(std::shared_ptr<GC> gc,
|
|||||||
TClass cls;
|
TClass cls;
|
||||||
cls.documentation = GetString(stream);
|
cls.documentation = GetString(stream);
|
||||||
uint32_t name_cnt = EnsureInt(stream);
|
uint32_t name_cnt = EnsureInt(stream);
|
||||||
|
cls.name.reserve((size_t)name_cnt);
|
||||||
for (uint32_t k = 0; k < name_cnt; k++) {
|
for (uint32_t k = 0; k < name_cnt; k++) {
|
||||||
cls.name.push_back(GetString(stream));
|
cls.name.push_back(GetString(stream));
|
||||||
}
|
}
|
||||||
name_cnt = EnsureInt(stream);
|
name_cnt = EnsureInt(stream);
|
||||||
|
cls.inherits.reserve((size_t)name_cnt);
|
||||||
for (uint32_t k = 0; k < name_cnt; k++) {
|
for (uint32_t k = 0; k < name_cnt; k++) {
|
||||||
cls.inherits.push_back(GetString(stream));
|
cls.inherits.push_back(GetString(stream));
|
||||||
}
|
}
|
||||||
name_cnt = EnsureInt(stream);
|
name_cnt = EnsureInt(stream);
|
||||||
|
cls.entry.reserve((size_t)name_cnt);
|
||||||
for (uint32_t k = 0; k < name_cnt; k++) {
|
for (uint32_t k = 0; k < name_cnt; k++) {
|
||||||
TClassEntry ent;
|
TClassEntry ent;
|
||||||
Ensure(stream, main_header, 1);
|
Ensure(stream, main_header, 1);
|
||||||
@@ -359,12 +389,15 @@ void TFile::Load(std::shared_ptr<GC> gc,
|
|||||||
ent.documentation = GetString(stream);
|
ent.documentation = GetString(stream);
|
||||||
ent.name = GetString(stream);
|
ent.name = GetString(stream);
|
||||||
uint32_t arglen = EnsureInt(stream);
|
uint32_t arglen = EnsureInt(stream);
|
||||||
|
ent.args.reserve((size_t)arglen);
|
||||||
for (uint32_t l = 0; l < arglen; l++)
|
for (uint32_t l = 0; l < arglen; l++)
|
||||||
ent.args.push_back(GetString(stream));
|
ent.args.push_back(GetString(stream));
|
||||||
ent.chunkId = EnsureInt(stream);
|
ent.chunkId = EnsureInt(stream);
|
||||||
cls.entry.push_back(ent);
|
cls.entry.push_back(ent);
|
||||||
}
|
}
|
||||||
|
gc->BarrierBegin();
|
||||||
this->classes.push_back(cls);
|
this->classes.push_back(cls);
|
||||||
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
} else if (strncmp(table_name, "META", 4) == 0) // structured metadata
|
} else if (strncmp(table_name, "META", 4) == 0) // structured metadata
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2042,7 +2042,8 @@ bool InterperterThread::DeclareConstVariable(std::shared_ptr<GC> gc) {
|
|||||||
|
|
||||||
throw VMException(
|
throw VMException(
|
||||||
"[DECLARECONSTVARIABLE] Can't pop string, got type " +
|
"[DECLARECONSTVARIABLE] Can't pop string, got type " +
|
||||||
GetObjectTypeString(key) + " = " + ToString(gc, key) + ".");
|
GetObjectTypeString(key) + " = " + ObjectToString(gc, key) +
|
||||||
|
".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -2060,10 +2061,8 @@ bool InterperterThread::PushResourceStream(std::shared_ptr<GC> gc) {
|
|||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
// TByteArray* arr = TByteArray::Create(ls);
|
stk->Push(gc, ls.Create<TStream>(std::make_shared<EmbedStream>(
|
||||||
// arr->data = stk->callable->file->resources[n];
|
gc, stk->callable->file->resources[n])));
|
||||||
stk->Push(
|
|
||||||
gc, std::make_shared<EmbedStream>(gc, stk->callable->file, n));
|
|
||||||
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
} else {
|
} else {
|
||||||
@@ -2086,9 +2085,9 @@ bool InterperterThread::PushResource(std::shared_ptr<GC> gc) {
|
|||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TByteArray *arr = TByteArray::Create(ls);
|
|
||||||
arr->data = stk->callable->file->resources[n];
|
stk->Push(gc,
|
||||||
stk->Push(gc, arr);
|
ls.Create<TByteArray>(stk->callable->file->resources[n]));
|
||||||
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
} else {
|
} else {
|
||||||
@@ -2379,7 +2378,7 @@ bool InterperterThread::CreateArray(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();
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TList *dict = TList::Create(ls);
|
TList *dict = ls.Create<TList>();
|
||||||
stk->Push(gc, dict);
|
stk->Push(gc, dict);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2910,7 +2909,7 @@ void InterperterThread::AddCallStackEntry(GCList &ls, TClosure *closure,
|
|||||||
: closure->env;
|
: closure->env;
|
||||||
cse->ip = 0;
|
cse->ip = 0;
|
||||||
if (closure->closure->args.empty() && closure->chunkId != 0) {
|
if (closure->closure->args.empty() && closure->chunkId != 0) {
|
||||||
TList *list = TList::Create(ls);
|
TList *list = ls.Create<TList>();
|
||||||
list->items = args;
|
list->items = args;
|
||||||
cse->env->DeclareVariable("arguments", list);
|
cse->env->DeclareVariable("arguments", list);
|
||||||
|
|
||||||
@@ -2974,7 +2973,7 @@ void InterperterThread::AddCallStackEntry(GCList &ls, TClosure *closure,
|
|||||||
if (i == closure->closure->args.size() - 1 && back.size() > 2 &&
|
if (i == closure->closure->args.size() - 1 && back.size() > 2 &&
|
||||||
back[0] == '$' && back[1] == '$') {
|
back[0] == '$' && back[1] == '$') {
|
||||||
auto argName = closure->closure->args[i];
|
auto argName = closure->closure->args[i];
|
||||||
auto lsArgs = TList::Create(ls);
|
auto lsArgs = ls.Create<TList>();
|
||||||
for (; i < args.size(); i++)
|
for (; i < args.size(); i++)
|
||||||
lsArgs->Add(args[i]);
|
lsArgs->Add(args[i]);
|
||||||
cse->env->DeclareVariable(trimStart(argName), lsArgs);
|
cse->env->DeclareVariable(trimStart(argName), lsArgs);
|
||||||
|
|||||||
Reference in New Issue
Block a user