From fca18e63a61a4d80b060a1145f9909c678afe2e4 Mon Sep 17 00:00:00 2001 From: Mike Nolan Date: Thu, 30 Apr 2026 10:07:14 -0500 Subject: [PATCH] Commit before replacing GC* with std::shared_ptr --- include/CrossLang.hpp | 485 +++++++++++++------------- src/programs/crosslanginterperter.cpp | 4 +- src/programs/crosslangvm.cpp | 5 +- src/programs/slim.cpp | 76 ++-- src/runtime_methods/std.cpp | 9 +- src/types/vfsheapobject.cpp | 384 +++++--------------- src/vm/bc/executemethod2.cpp | 32 ++ src/vm/gc.cpp | 65 ++-- src/vm/gclist.cpp | 4 +- 9 files changed, 454 insertions(+), 610 deletions(-) diff --git a/include/CrossLang.hpp b/include/CrossLang.hpp index 4aea2da..a68ac37 100644 --- a/include/CrossLang.hpp +++ b/include/CrossLang.hpp @@ -34,7 +34,7 @@ /** * @namespace Tesses::CrossLang * @brief The CrossLang namespace - * + * */ namespace Tesses::CrossLang { using BitConverter = Tesses::Framework::Serialization::BitConverter; @@ -42,7 +42,7 @@ namespace Tesses::CrossLang { constexpr std::string_view VMHowToGet = "https://crosslang.tesseslanguage.com/"; /** * @brief Escape a crosslang string (for generating source code) - * + * * @param text text to escape * @param quote whether to surround with double quotes * @return std::string the escaped string @@ -51,7 +51,7 @@ namespace Tesses::CrossLang { /** * @brief Get the config folder used by crosslang - * + * * @return Tesses::Framework::Filesystem::VFSPath the config folder for crosslang */ Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir(); @@ -60,7 +60,7 @@ namespace Tesses::CrossLang { /** * @brief Version stage - * + * */ enum TVMVersionStage : uint8_t { @@ -71,7 +71,7 @@ namespace Tesses::CrossLang { }; /** * @brief CrossLang version - * + * */ class TVMVersion { @@ -82,7 +82,7 @@ namespace Tesses::CrossLang { public: /** * @brief Major - * + * * @return uint8_t The major */ uint8_t Major() @@ -91,7 +91,7 @@ namespace Tesses::CrossLang { } /** * @brief Minor - * + * * @return uint8_t The minor */ uint8_t Minor() @@ -100,7 +100,7 @@ namespace Tesses::CrossLang { } /** * @brief Patch - * + * * @return uint8_t The patch */ uint8_t Patch() @@ -109,7 +109,7 @@ namespace Tesses::CrossLang { } /** * @brief Build - * + * * @return uint16_t The build */ uint16_t Build() @@ -118,7 +118,7 @@ namespace Tesses::CrossLang { } /** * @brief Stage (dev, alpha, beta or prod) - * + * * @return TVMVersionStage The stage */ TVMVersionStage VersionStage() @@ -127,7 +127,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Major - * + * * @param major The major */ void SetMajor(uint8_t major) @@ -136,7 +136,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Minor - * + * * @param minor The minor */ void SetMinor(uint8_t minor) @@ -145,7 +145,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Patch - * + * * @param patch The patch */ void SetPatch(uint8_t patch) @@ -154,7 +154,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Build - * + * * @param build The build << 2 | (stage & 3) */ void SetBuild(uint16_t build) @@ -163,9 +163,9 @@ namespace Tesses::CrossLang { } /** * @brief Set the Build (and stage) - * - * @param build - * @param version + * + * @param build + * @param version */ void SetBuild(uint16_t build,TVMVersionStage version) { @@ -173,7 +173,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Version - * + * * @param major The major * @param minor The minor * @param patch The patch @@ -189,7 +189,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Version - * + * * @param major The major * @param minor The minor * @param patch The patch @@ -204,7 +204,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Version - * + * * @param major The major * @param minor The minor * @param patch The patch @@ -217,7 +217,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the Version - * + * * @param versionData same order as SetVersion(uint8_t major, uint8_t minor, uint8_t patch, uint8_t buildHigh, uint8_t buildLow) but is a pointer to uint8_t version[5] */ void SetVersion(uint8_t* versionData) @@ -226,7 +226,7 @@ namespace Tesses::CrossLang { } /** * @brief Set the version from long - * + * * @param v version serialized as long */ void SetFromLong(uint64_t v) @@ -239,7 +239,7 @@ namespace Tesses::CrossLang { } /** * @brief Encodes the version to bytes to be decoded by SetVersion(uint8_t*) or the constructor - * + * * @param versionData an array that is 5 bytes long */ void ToArray(uint8_t* versionData) @@ -252,12 +252,12 @@ namespace Tesses::CrossLang { } /** * @brief Construct a new Version object - * + * * @param major Major * @param minor Minor * @param patch Patch * @param build Build - * @param version Stage (dev, alpha, beta, prod) see TVMVersionStage for actual names + * @param version Stage (dev, alpha, beta, prod) see TVMVersionStage for actual names */ TVMVersion(uint8_t major, uint8_t minor, uint8_t patch, uint16_t build, TVMVersionStage version) { @@ -265,7 +265,7 @@ namespace Tesses::CrossLang { } /** * @brief Construct a new Version object - * + * * @param versionData same order as SetVersion(uint8_t major, uint8_t minor, uint8_t patch, uint8_t buildHigh, uint8_t buildLow) but is a pointer to uint8_t version[5] */ TVMVersion(uint8_t* versionData) @@ -274,7 +274,7 @@ namespace Tesses::CrossLang { } /** * @brief Construct a new 1.0.0.0-dev Version object - * + * */ TVMVersion() { @@ -285,7 +285,7 @@ namespace Tesses::CrossLang { } /** * @brief Construct a new Version object from a long - * + * * @param v version serialized as long */ TVMVersion(uint64_t v) @@ -294,7 +294,7 @@ namespace Tesses::CrossLang { } /** * @brief Compares to another version - * + * * @param version another version object * @return int returns 1 if this is newer than other version, 0 if same, -1 if this is older than other version */ @@ -312,7 +312,7 @@ namespace Tesses::CrossLang { } /** * @brief Serializes to a long - * + * * @return uint64_t serialized as a long */ uint64_t AsLong() @@ -325,7 +325,7 @@ namespace Tesses::CrossLang { } /** * @brief Compares this to the runtime version (for Bytecode) - * + * * @return int CompareTo(RuntimeVersion) where RuntimeVersion is the runtime version */ int CompareToRuntime() @@ -335,7 +335,7 @@ namespace Tesses::CrossLang { } /** * @brief Try to parse the version from a string - * + * * @param versionStr the version string like 1.0.0.0-prod (or dev, alpha, beta) * @param version a reference to a version * @return true the parsing succeeded @@ -354,10 +354,10 @@ namespace Tesses::CrossLang { left = versionStr.substr(0, sep); right = versionStr.substr(sep+1); } - + if(left.empty()) return false; - + TVMVersionStage stage; if(right == "dev") @@ -370,7 +370,7 @@ namespace Tesses::CrossLang { stage = TVMVersionStage::ProductionVersion; else return false; - + //1 0.0.0 sep=left.find_first_of('.'); @@ -378,7 +378,7 @@ namespace Tesses::CrossLang { if(sep != std::string::npos) { auto lStr = left.substr(0, sep); - + right = left.substr(sep+1); left = lStr; } @@ -395,7 +395,7 @@ namespace Tesses::CrossLang { if(sep != std::string::npos) { auto lStr = left.substr(0, sep); - + right = left.substr(sep+1); left = lStr; } @@ -412,7 +412,7 @@ namespace Tesses::CrossLang { if(sep != std::string::npos) { auto lStr = left.substr(0, sep); - + right = left.substr(sep+1); left = lStr; } @@ -430,7 +430,7 @@ namespace Tesses::CrossLang { } /** * @brief Converts version to string - * + * * @return std::string the version string like 1.0.0.0-prod (or dev, alpha, beta) */ std::string ToString() @@ -465,7 +465,7 @@ namespace Tesses::CrossLang { /** * @brief Create a crvm archive file - * + * * @param vfs the filesystem used as root of the archive * @param strm the output stream * @param name the crvm name @@ -475,8 +475,8 @@ namespace Tesses::CrossLang { */ void CrossArchiveCreate(std::shared_ptr vfs,std::shared_ptr strm,std::string name,TVMVersion version,std::string info, std::string icon=""); /** - * @brief - * + * @brief + * * @param strm the input stream * @param vfs vfs to extract to (as root) * @return std::pair,std::string> ((name, version),info) @@ -487,7 +487,7 @@ namespace Tesses::CrossLang { /** * @brief The token type for lexer - * + * */ typedef enum { Identifier, @@ -498,40 +498,40 @@ typedef enum { } LexTokenType; /** * @brief The line info for lextoken - * + * */ class LexTokenLineInfo { public: /** * @brief line number - * + * */ int line; /** * @brief column number - * + * */ int column; /** * @brief byte offset in file - * + * */ int offset; /** * @brief filename - * + * */ std::string filename; /** * @brief Add a char - * + * * @param c a char to add to line, column, offset */ void Add(int c); /** * @brief Subtract from column and offset - * + * * @param c the number of chars */ void Subtract(size_t c); @@ -539,34 +539,34 @@ typedef enum { /** * @brief The lextoken for lexer - * + * */ class LexToken { public: /** * @brief line information - * + * */ LexTokenLineInfo lineInfo; /** * @brief the token type - * + * */ LexTokenType type; /** * @brief the token text - * + * */ std::string text; /** * @brief any white space characters before this token - * + * */ std::string whiteSpaceCharsBefore; }; /** * @brief Start lexing the file - * + * * @param filename the filename used for exception purposes * @param strm the character stream * @param tokens the tokens @@ -578,7 +578,7 @@ using Undefined = std::monostate; class AdvancedSyntaxNode; /** * @brief Bytecode instruction enumeration - * + * */ typedef enum { ADD, @@ -651,19 +651,19 @@ typedef enum { } Instruction; /** * @brief Base type for bytecode instruction - * + * */ class ByteCodeInstruction { public: /** * @brief Size of instruction - * + * * @return size_t the length of the instruction */ virtual size_t Size()=0; /** * @brief Write the instruction to vector - * + * * @param data the vector of uint8_t */ virtual void Write(std::vector& data)=0; @@ -672,30 +672,30 @@ class ByteCodeInstruction { }; /** * @brief Basic bytecode instruction - * + * */ class SimpleInstruction : public ByteCodeInstruction { public: /** * @brief The instruction - * + * */ Instruction instruction; /** * @brief Construct a new Simple Instruction object - * + * * @param instr the instruction */ SimpleInstruction(Instruction instr); /** * @brief Size of instruction - * + * * @return size_t 1, because simple instructions are just an instruction */ size_t Size(); /** * @brief Write the opcode to the vector - * + * * @param data the vector of uint8_t */ void Write(std::vector& data); @@ -734,7 +734,7 @@ class LabelableInstruction : public ByteCodeInstruction { class JumpStyleInstruction : public LabelableInstruction { public: Instruction type; - + JumpStyleInstruction(Instruction conditional,std::string label); size_t Size(); void Write(std::vector& data); @@ -815,7 +815,7 @@ class ResourceBase { virtual bool IsEqual(ResourceBase* base); }; -class ResourceFile : public ResourceBase +class ResourceFile : public ResourceBase { std::shared_ptr strm=nullptr; public: @@ -840,7 +840,7 @@ class ResourceByteArray : public ResourceBase class CodeGen { uint32_t id; uint32_t NewId(); - + void GetFunctionArgs(std::vector& args,SyntaxNode n); void GetFunctionName(std::vector& name,SyntaxNode n); void GetFunctionArgs(std::vector& args,SyntaxNode n); @@ -850,7 +850,7 @@ class CodeGen { uint32_t GetResource(std::shared_ptr resource); std::vector strs; std::vector> res; - + std::vector, std::vector>> chunks; std::vector,uint32_t>> funcs; std::vector classes; @@ -874,298 +874,298 @@ class CodeGen { }; /** * @brief A html expression - * + * */ constexpr std::string_view HtmlRootExpression = "htmlRootExpression"; /** * @brief an intrinsic function that embeds a resource from the filename based on the constant string argument - * + * */ constexpr std::string_view EmbedExpression = "embedExpression"; /** * @brief an intrinsic function that embeds a resource as a stream from the filename based on the constant string argument - * + * */ constexpr std::string_view EmbedStreamExpression = "embedStreamExpression"; /** * @brief an intrinsic function that embeds a resource directory from the directory name based on the constant string argument - * + * */ constexpr std::string_view EmbedDirectoryExpression = "embedDirectoryExpression"; /** * @brief Negative operator -EXPR - * + * */ constexpr std::string_view NegativeExpression = "negativeExpression"; /** * @brief Not operator !EXPR - * + * */ constexpr std::string_view NotExpression = "notExpression"; /** * @brief Bitwise not operator ~EXPR - * + * */ constexpr std::string_view BitwiseNotExpression = "bitwiseNotExpression"; /** * @brief ++i - * + * */ constexpr std::string_view PrefixIncrementExpression = "prefixIncrementExpression"; /** * @brief --i - * + * */ constexpr std::string_view PrefixDecrementExpression = "prefixDecrementExpression"; /** * @brief i++ - * + * */ constexpr std::string_view PostfixIncrementExpression = "postfixIncrementExpression"; /** * @brief i-- - * + * */ constexpr std::string_view PostfixDecrementExpression = "postfixDecrementExpression"; /** * @brief Gets variable value - * + * */ constexpr std::string_view GetVariableExpression = "getVariableExpression"; /** * @brief Get field or get property (EXPR.getNAME()) (unless it is wrapped in AssignExpression) which then it sets the field or calls EXPR.setNAME(VALUE) - * + * */ constexpr std::string_view GetFieldExpression = "getFieldExpression"; /** * @brief Syntax sugar for EXPR.GetAt(index) (unless it is wrapped in AssignExpresion) which then it is EXPR.SetAt(index, VALUE) - * + * */ constexpr std::string_view GetArrayExpression = "getArrayExpression"; /** * @brief Function Call myFn() or MyDict.Fn() - * + * */ constexpr std::string_view FunctionCallExpression = "functionCallExpression"; /** * @brief Used for compound assignment like VAR += EXPR - * + * */ constexpr std::string_view CompoundAssignExpression = "compoundAssignExpression"; /** * @brief Assign something using = - * + * */ constexpr std::string_view AssignExpression = "assignExpression"; /** * @brief A char litteral - * + * */ constexpr std::string_view CharExpression = "charExpression"; /** * @brief The undefined literal - * + * */ constexpr std::string_view UndefinedExpression = "undefinedExpression"; /** * @brief A list of nodes that does create a new scope - * + * */ constexpr std::string_view ScopeNode = "scopeNode"; /** * @brief A list of nodes that doesn't create a new scope - * + * */ constexpr std::string_view NodeList = "nodeList"; /** * @brief Array expresion [1,2,10] - * + * */ constexpr std::string_view ArrayExpression = "arrayExpression"; /** * @brief Dictionary expression { a = 42, b = false} - * + * */ constexpr std::string_view DictionaryExpression = "dictionaryExpression"; /** * @brief var v = 59; - * + * */ constexpr std::string_view DeclareExpression = "declareExpression"; /** * @brief const v = 59; - * + * */ constexpr std::string_view ConstExpression = "constExpression"; /** * @brief Closure expression (a,b)=> a * b - * + * */ constexpr std::string_view ClosureExpression = "closureExpression"; /** * @brief Just like normal closures but doesn't create its own scope - * + * */ constexpr std::string_view ScopelessClosureExpression = "scopelessClosureExpression"; /** * @brief Ternary operator COND ? EXPR : EXPR - * + * */ constexpr std::string_view TernaryExpression = "ternaryExpression"; /** * @brief If statement if(COND) {} else if(COND) {} else {} - * + * */ constexpr std::string_view IfStatement = "ifStatement"; /** * @brief For statement for(var i = 0; i < 42; i++) - * + * */ constexpr std::string_view ForStatement = "forStatement"; /** * @brief While statement while(COND) - * + * */ constexpr std::string_view WhileStatement = "whileStatement"; /** * @brief Do statement do(COND) - * + * */ constexpr std::string_view DoStatement = "doStatement"; /** * @brief Each statement each(var item : EXPR) - * + * */ constexpr std::string_view EachStatement = "eachStatement"; /** * @brief Return statement return EXPR; - * + * */ constexpr std::string_view ReturnStatement = "returnStatement"; /** * @brief Break statement break; - * + * */ constexpr std::string_view BreakStatement = "breakStatement"; /** * @brief Continue statement continue; - * + * */ constexpr std::string_view ContinueStatement = "continueStatement"; /** * @brief Function statement func main(args) - * + * */ constexpr std::string_view FunctionStatement = "functionStatement"; /** * @brief The documentation statement /^ Documentation ^/ func main(args) {} - * + * */ constexpr std::string_view DocumentationStatement = "documentationStatement"; /** * @brief The comma expression EXPR, EXPR - * + * */ constexpr std::string_view CommaExpression = "commaExpression"; /** * @brief The addition operator EXPR + EXPR - * + * */ constexpr std::string_view AddExpression = "addExpression"; /** * @brief The subtraction operator EXPR - EXPR - * + * */ constexpr std::string_view SubExpression = "subtractExpression"; /** * @brief The times operator EXPR * EXPR - * + * */ constexpr std::string_view TimesExpression = "timesExpression"; /** * @brief The divsion operator EXPR / EXPR - * + * */ constexpr std::string_view DivideExpression = "divideExpression"; /** * @brief The modulo operator (get remainder) EXPR % EXPR - * + * */ constexpr std::string_view ModExpression = "modExpression"; /** * @brief The left shift operator EXPR << EXPR - * + * */ constexpr std::string_view LeftShiftExpression = "leftShiftExpression"; /** * @brief The right shift operator EXPR >> EXPR - * + * */ constexpr std::string_view RightShiftExpression = "rightShiftExpression"; /** * @brief The bitwise or expression EXPR | EXPR - * + * */ constexpr std::string_view BitwiseOrExpression = "bitwiseOrExpression"; /** * @brief The bitwise and expression EXPR & EXPR - * + * */ constexpr std::string_view BitwiseAndExpression = "bitwiseAndExpression"; /** * @brief The xor expression EXPR ^ EXPR - * + * */ constexpr std::string_view XOrExpression = "xOrExpression"; /** * @brief The logical or expression EXPR || EXPR - * + * */ constexpr std::string_view LogicalOrExpression = "logicalOrExpression"; /** * @brief The logical and expression EXPR && EXPR - * + * */ constexpr std::string_view LogicalAndExpression = "logicalAndExpression"; /** * @brief The equals expression EXPR == EXPR - * + * */ constexpr std::string_view EqualsExpression = "equalsExpression"; /** * @brief The not equals expression EXPR != EXPR - * + * */ constexpr std::string_view NotEqualsExpression = "notEqualsExpression"; /** * @brief The less than expression EXPR < EXPR - * + * */ constexpr std::string_view LessThanExpression = "lessThanExpression"; /** * @brief The greater than expression EXPR > EXPR - * + * */ constexpr std::string_view GreaterThanExpression = "greaterThanExpression"; /** * @brief The less than equals expression EXPR <= EXPR - * + * */ constexpr std::string_view LessThanEqualsExpression = "lessThanEqualsExpression"; /** * @brief The greater than equals expression EXPR >= EXPR - * + * */ constexpr std::string_view GreaterThanEqualsExpression = "greaterThanEqualsExpression"; /** * @brief The parentheses expression (expression) - * + * */ constexpr std::string_view ParenthesesExpression = "parenthesesExpression"; /** * @brief The throw statement - * + * */ constexpr std::string_view ThrowStatement = "throwStatement"; /** @@ -1174,42 +1174,42 @@ constexpr std::string_view ThrowStatement = "throwStatement"; constexpr std::string_view BreakpointStatement = "breakpointStatement"; /** * @brief The try statement - * + * */ constexpr std::string_view TryStatement = "tryStatement"; /** * @brief The defer statement - * + * */ constexpr std::string_view DeferStatement = "deferStatement"; /** * @brief The defer statement - * + * */ constexpr std::string_view YieldStatement = "yieldStatement"; /** * @brief The enumerable statement - * + * */ constexpr std::string_view EnumerableStatement = "enumerableStatement"; /** * @brief The switch statement - * + * */ constexpr std::string_view SwitchStatement = "switchStatement"; /** * @brief Case clause of switch statement - * + * */ constexpr std::string_view CaseStatement = "caseStatement"; /** * @brief Default clause of switch statement - * + * */ constexpr std::string_view DefaultStatement = "defaultStatement"; /** * @brief Class statement (not implemented) - * + * */ constexpr std::string_view ClassStatement = "classStatement"; /** @@ -1229,12 +1229,12 @@ constexpr std::string_view AbstractMethodStatement = "abstractMethodStatement"; constexpr std::string_view FieldStatement = "fieldStatement"; /** * @brief Root path expression / "path" / "to" / "file" (fullfils the first /) - * + * */ constexpr std::string_view RootPathExpression = "rootPathExpression"; /** * @brief The relative path expression ./ "path" / "to" / "subdir" (fullfills the ./) - * + * */ constexpr std::string_view RelativePathExpression = "relativePathExpression"; /** @@ -1256,28 +1256,28 @@ constexpr std::string_view MetadataStatement = "MetadataStatement"; /** * @brief Advanced AST node - * + * */ class AdvancedSyntaxNode { public: /** * @brief The name of the advanced AST node - * + * */ std::string nodeName; /** * @brief The advanced syntax node is an expression - * + * */ bool isExpression; /** * @brief The subnodes of the abstract syntax node - * + * */ std::vector nodes; /** * @brief Create abstract syntax node - * + * * @param nodeName The name of the advanced AST node * @param isExpression The advanced syntax node is an expression * @param n The subnodes of the abstract syntax node @@ -1295,21 +1295,21 @@ class GC; class TRootEnvironment; /** * @brief Token Parser - * + * */ class Parser { uint32_t id; uint32_t NewId(); uint64_t i; std::vector tokens; - + LexToken tkn; void EnsureSymbol(std::string txt); bool IsIdentifier(std::string txt,bool pop=true); bool IsAnyIdentifier(std::initializer_list idents, bool pop=true); bool IsSymbol(std::string txt,bool pop=true); bool IsAnySymbol(std::initializer_list idents, bool pop=true); - + SyntaxNode ParseExpression(); SyntaxNode ParseTernary(); SyntaxNode ParseNode(bool isRoot=false); @@ -1337,14 +1337,14 @@ class Parser { bool debug=true; /** * @brief Construct a new Parser object - * + * * @param tokens the tokens from lexer */ Parser(std::vector tokens); Parser(std::vector tokens, GC* gc, TRootEnvironment* env); /** * @brief Turn tokens into abstract syntax tree - * + * * @return SyntaxNode the abstract syntax tree */ SyntaxNode ParseRoot() @@ -1362,16 +1362,16 @@ class Parser { { marked = true; } - + virtual ~THeapObject() { } - + }; - - + + class THeapObjectHolder { public: @@ -1382,7 +1382,7 @@ class Parser { } THeapObjectHolder() { - + } }; @@ -1392,7 +1392,7 @@ class Parser { class MethodInvoker { }; - + class TBreak { @@ -1402,7 +1402,7 @@ class TContinue { }; /** * @brief A script object - * + * */ using TObject = std::variant,std::shared_ptr,TBreak,TContinue,std::shared_ptr,std::shared_ptr,std::shared_ptr,std::shared_ptr,std::shared_ptr,std::shared_ptr,std::shared_ptr,std::shared_ptr, Tesses::Framework::Uuid>; @@ -1441,9 +1441,9 @@ class GC { std::string ToString(GC* gc, TObject obj); class GCList : public THeapObject - { + { std::vector items; - + GC* gc; public: GCList(GC* gc); @@ -1453,18 +1453,18 @@ class GC { void Remove(TObject v); void Mark(); - - - ~GCList(); + + ~GCList(); + friend class GC; }; - - + + class TFile; - + class TFileChunk : public THeapObject { public: @@ -1476,10 +1476,10 @@ class GC { std::optional name; void Mark(); }; - - - + + + class TByteArray : public THeapObject { public: @@ -1494,7 +1494,7 @@ class GC { Static }; class TClassEntry { - public: + public: TClassModifier modifier; bool isFunction; @@ -1511,7 +1511,7 @@ class GC { std::vector name; std::vector inherits; std::vector entry; - + }; class TClassObjectEntry { public: @@ -1526,11 +1526,11 @@ class GC { class TFile : public THeapObject { public: - + static TFile* Create(GCList* gc); static TFile* Create(GCList& gc); std::vector chunks; - + std::vector strings; std::vector> vms; std::vector, uint32_t>> functions; @@ -1544,7 +1544,7 @@ class GC { TVMVersion version; std::string info; int32_t icon; - + void Load(GC* gc, std::shared_ptr strm); void Skip(std::shared_ptr strm,size_t len); void Ensure(std::shared_ptr strm,uint8_t* buffer, size_t len); @@ -1573,7 +1573,7 @@ class GC { int64_t Count(); void Mark(); }; - + class TList : public THeapObject { @@ -1651,9 +1651,9 @@ class GC { { return Create(gc, il.begin(),il.end()); } - - + + virtual bool HasValue(std::string key); virtual bool MethodExists(GCList& ls,std::string key); virtual TObject GetValue(std::string key); @@ -1667,7 +1667,7 @@ class GC { TObject CallMethodWithFatalError(GCList& ls, std::string key, std::vector args); }; - + class TRootEnvironment; class TSubEnvironment; @@ -1696,14 +1696,14 @@ class GC { TObject Eval(GCList& ls,std::string code); virtual bool HasVariable(std::string key)=0; virtual bool HasVariableRecurse(std::string key)=0; - + virtual bool HasVariableOrFieldRecurse(std::string key,bool setting=false)=0; virtual TObject GetVariable(std::string key)=0; - + virtual TObject GetVariable(GCList& ls, std::string key)=0; virtual TObject SetVariable(GCList& ls, std::string key, TObject v)=0; - + virtual void SetVariable(std::string key, TObject value)=0; TDictionary* EnsureDictionary(GC* gc, std::string key); virtual void DeclareVariable(std::string key, TObject value)=0; @@ -1725,7 +1725,7 @@ class GC { TObject CallFunctionWithFatalError(GCList& ls, std::string key, std::vector args); }; class TClassEnvironment; - class TClassObject : public THeapObject + class TClassObject : public THeapObject { TClassObjectEntry* GetEntry(std::string classN, std::string key); public: @@ -1736,7 +1736,7 @@ class GC { std::string name; std::vector inherit_tree; std::vector entries; - + static TClassObject* Create(GCList& ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector args); static TClassObject* Create(GCList* ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector args); @@ -1760,22 +1760,22 @@ class GC { bool HasVariable(std::string key); bool HasVariableRecurse(std::string key); bool HasVariableOrFieldRecurse(std::string key, bool setting=false); - + TObject GetVariable(std::string key); void SetVariable(std::string key, TObject value); TObject GetVariable(GCList& ls, std::string key); TObject SetVariable(GCList& ls, std::string key, TObject v); - + void DeclareVariable(std::string key, TObject value); bool HasConstForSet(std::string key); TRootEnvironment* GetRootEnvironment(); TEnvironment* GetParentEnvironment(); - + void Mark(); }; - - + + class EnvironmentPermissions { public: EnvironmentPermissions(); @@ -1805,7 +1805,7 @@ class GC { { TDictionary* dict; TCallable* error=nullptr; - + void LoadDependency(GC* gc,std::shared_ptr vfs, std::pair dep); public: EnvironmentPermissions permissions; @@ -1814,10 +1814,10 @@ class GC { std::vector> classes; bool TryFindClass(std::vector& name, size_t& index); - + void LoadFileWithDependencies(GC* gc,std::shared_ptr vfs, TFile* f); void LoadFileWithDependencies(GC* gc,std::shared_ptr vfs, Tesses::Framework::Filesystem::VFSPath path); - + TDictionary* GetDictionary(); static TRootEnvironment* Create(GCList* gc,TDictionary* dict); static TRootEnvironment* Create(GCList& gc,TDictionary* dict); @@ -1825,10 +1825,10 @@ class GC { bool HasVariable(std::string key); bool HasVariableRecurse(std::string key); bool HasVariableOrFieldRecurse(std::string key,bool setting=false); - + TObject GetVariable(std::string key); void SetVariable(std::string key, TObject value); - + TObject GetVariable(GCList& ls, std::string key); TObject SetVariable(GCList& ls, std::string key, TObject v); void DeclareVariable(std::string key, TObject value); @@ -1859,7 +1859,7 @@ class GC { static void RegisterEnv(GC* gc, TRootEnvironment* env); static void RegisterProcess(GC* gc, TRootEnvironment* env); static void RegisterClass(GC* gc, TRootEnvironment* env); - + }; class TSubEnvironment : public TEnvironment @@ -1879,7 +1879,7 @@ class GC { void SetVariable(std::string key, TObject value); TObject GetVariable(GCList& ls, std::string key); TObject SetVariable(GCList& ls, std::string key, TObject v); - + void DeclareVariable(std::string key, TObject value); TRootEnvironment* GetRootEnvironment(); TEnvironment* GetParentEnvironment(); @@ -1887,7 +1887,7 @@ class GC { void Mark(); }; - + TDictionary* CreateThread(GCList& ls, TCallable* callable,bool detached); class TArgWrapper : public TCallable @@ -1904,8 +1904,8 @@ class GC { { std::function args)> cb; std::function destroy; - - public: + + public: std::vector args; std::vector watch; TExternalMethod(std::function args)> cb,std::string documentation, std::vector argNames,std::function destroy); @@ -1925,9 +1925,9 @@ class GC { GC::Mark(item); GC::Mark(this->tag); } - + }; - + class TEnumerator : public THeapObject { public: @@ -1935,7 +1935,7 @@ class GC { virtual TObject GetCurrent(GCList& ls)=0; static TEnumerator* CreateFromObject(GCList& ls, TObject obj); }; - class TAssociativeArrayEnumerator : public TEnumerator + class TAssociativeArrayEnumerator : public TEnumerator { int64_t index; TAssociativeArray* ls; @@ -1955,7 +1955,7 @@ class GC { void Mark(); static TCustomEnumerator* Create(GCList& ls,TDictionary* dict); static TCustomEnumerator* Create(GCList* ls,TDictionary* dict); - + }; class TYieldEnumerator : public TEnumerator @@ -1969,10 +1969,10 @@ class GC { void Mark(); static TYieldEnumerator* Create(GCList& ls,TObject v); static TYieldEnumerator* Create(GCList* ls,TObject v); - + }; - - class TStringEnumerator : public TEnumerator + + class TStringEnumerator : public TEnumerator { bool hasStarted; size_t index; @@ -1983,8 +1983,8 @@ class GC { bool MoveNext(GC* ls); TObject GetCurrent(GCList& ls); }; - - class TListEnumerator : public TEnumerator + + class TListEnumerator : public TEnumerator { int64_t index; TList* ls; @@ -1997,7 +1997,7 @@ class GC { }; class TDynamicList; class TDynamicDictionary; - class TDynamicListEnumerator : public TEnumerator + class TDynamicListEnumerator : public TEnumerator { int64_t index; TDynamicList* ls; @@ -2016,11 +2016,11 @@ class GC { static TVFSPathEnumerator* Create(GCList* ls, Tesses::Framework::Filesystem::VFSPathEnumerator list); bool MoveNext(GC* ls); TObject GetCurrent(GCList& ls); - + }; - + class TObjectVFS : public Tesses::Framework::Filesystem::VFS { public: @@ -2028,23 +2028,15 @@ class GC { GCList* ls; TObjectVFS(GC* gc, TObject obj); std::shared_ptr OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode); + Tesses::Framework::Filesystem::FIFOCreationResult CreateFIFO(Tesses::Framework::Filesystem::VFSPath path); void CreateDirectory(Tesses::Framework::Filesystem::VFSPath path); void DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path); - bool RegularFileExists(Tesses::Framework::Filesystem::VFSPath path); - bool SymlinkExists(Tesses::Framework::Filesystem::VFSPath path); - bool CharacterDeviceExists(Tesses::Framework::Filesystem::VFSPath path); - bool BlockDeviceExists(Tesses::Framework::Filesystem::VFSPath path); - bool SocketFileExists(Tesses::Framework::Filesystem::VFSPath path); - bool FIFOFileExists(Tesses::Framework::Filesystem::VFSPath path); - bool FileExists(Tesses::Framework::Filesystem::VFSPath path); - bool SpecialFileExists(Tesses::Framework::Filesystem::VFSPath path); void CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile); void CreateHardlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath newName); - bool DirectoryExists(Tesses::Framework::Filesystem::VFSPath path); void DeleteFile(Tesses::Framework::Filesystem::VFSPath path); void Lock(Tesses::Framework::Filesystem::VFSPath path); void Unlock(Tesses::Framework::Filesystem::VFSPath path); - + void DeleteDirectoryRecurse(Tesses::Framework::Filesystem::VFSPath path); Tesses::Framework::Filesystem::VFSPathEnumerator EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path); void MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest); @@ -2052,10 +2044,13 @@ class GC { Tesses::Framework::Filesystem::VFSPath ReadLink(Tesses::Framework::Filesystem::VFSPath path); std::string VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path); Tesses::Framework::Filesystem::VFSPath SystemToVFSPath(std::string path); - void GetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime& lastWrite, Tesses::Framework::Date::DateTime& lastAccess); void SetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime lastWrite, Tesses::Framework::Date::DateTime lastAccess); void Chmod(Tesses::Framework::Filesystem::VFSPath path, uint32_t mode); + void Chown(Tesses::Framework::Filesystem::VFSPath path, uint32_t uid, uint32_t gid); + bool StatVFS(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatVFSData& data); + + bool Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data); void Close(); ~TObjectVFS(); }; @@ -2081,7 +2076,7 @@ class GC { ~TObjectStream(); }; - + class TObjectHttpServer : public Tesses::Framework::Http::IHttpServer { @@ -2092,9 +2087,9 @@ class GC { bool Handle(Tesses::Framework::Http::ServerContext& ctx); ~TObjectHttpServer(); }; - - class TDictionaryEnumerator : public TEnumerator + + class TDictionaryEnumerator : public TEnumerator { bool hasStarted; std::map::iterator ittr; @@ -2160,7 +2155,7 @@ class GC { TObject SetField(GCList& ls, std::string key, TObject value); - TObject CallMethod(GCList& ls, std::string name, std::vector args); + TObject CallMethod(GCList& ls, std::string name, std::vector args); bool MethodExists(GCList& ls, std::string name); @@ -2170,7 +2165,7 @@ class GC { ~TDynamicDictionary(); }; class InterperterThread; - + class CallStackEntry : public THeapObject { public: @@ -2181,11 +2176,11 @@ class GC { TEnvironment* env; TClosure* callable; uint32_t ip; - uint32_t scopes; + uint32_t scopes; int64_t srcline; std::string srcfile; bool mustReturn; - + void Mark(); void Push(GC* gc,TObject v); TObject Pop(GCList& gcl); @@ -2223,7 +2218,7 @@ class GC { static TTask* FromResult(GCList& ls, TObject v); }; extern thread_local CallStackEntry* current_function; - + class InterperterThread : public THeapObject { private: @@ -2312,22 +2307,22 @@ class GC { void Mark(); }; - + class VMException : public std::exception { - + std::string error_message; public: - + VMException(std::string ex) { error_message = "VMException: "; error_message.append(ex); } - - + + const char * what() const noexcept override { return error_message.c_str(); @@ -2336,13 +2331,13 @@ class GC { class TAny : public THeapObject { public: std::any any; - TObject other; + TObject other; static TAny* Create(GCList& ls); static TAny* Create(GCList* ls); void Mark(); }; - class TNativeObject : public THeapObject + class TNativeObject : public THeapObject { public: template @@ -2386,7 +2381,7 @@ class GC { void* ptr; std::function destroy; public: - TObject other; + TObject other; TNative(void* ptr,std::function destroy); bool GetDestroyed(); void* GetPointer(); @@ -2397,7 +2392,7 @@ class GC { ~TNative(); }; - + class ThreadHandle : public THeapObject { public: @@ -2408,7 +2403,7 @@ class GC { TCallable* callable; TObject returnValue; GC* gc; - + void Mark() { @@ -2424,23 +2419,23 @@ class GC { this->thrd->Join(); delete this->thrd; } - + } }; - + TObject ExecuteFunction(GCList& ls,TCallable* callable,std::vector args); class VMByteCodeException : public std::exception { std::string lastErrorText; std::shared_ptr gcList; - + public: TObject exception; std::vector stack_trace; - + VMByteCodeException() { } @@ -2455,7 +2450,7 @@ class GC { for(auto item : this->stack_trace) gcList->Add(item); } - this->exception = obj; + this->exception = obj; UpdateError(); } @@ -2503,7 +2498,7 @@ class GC { LexTokenLineInfo LineInfo() { return line;} }; - + template bool GetObject(TObject& obj, T& res) { @@ -2585,7 +2580,7 @@ class GC { size_t offset; MarkedTObject file; uint32_t resource; - + public: EmbedStream(GC* gc, TFile* file, uint32_t resource); bool CanRead(); @@ -2620,9 +2615,9 @@ class GC { int64_t CrossArchiveExtract(std::vector& argv); TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector& argv); TObject CrossLangShell(GCList& ls, std::vector& argv); - + TObject CrossLangVM(GCList& ls,TRootEnvironment* env, std::vector& argv); - + void CrossLangDump(std::shared_ptr strm); void CrossLangCompiler(std::vector& argv); } diff --git a/src/programs/crosslanginterperter.cpp b/src/programs/crosslanginterperter.cpp index 5a0876c..f677346 100644 --- a/src/programs/crosslanginterperter.cpp +++ b/src/programs/crosslanginterperter.cpp @@ -6,12 +6,12 @@ using namespace Tesses::Framework; using namespace Tesses::CrossLang; using namespace Tesses::Framework::Filesystem; +static GC gc; int main(int argc, char** argv) { TF_InitWithConsole(); if(argc > 0) TF_AllowPortable(argv[0]); - GC gc; gc.Start(); GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); @@ -26,4 +26,4 @@ int main(int argc, char** argv) if(GetObject(res,myi64)) return (int)myi64; return 0; -} \ No newline at end of file +} diff --git a/src/programs/crosslangvm.cpp b/src/programs/crosslangvm.cpp index e0e846c..8bd59cc 100644 --- a/src/programs/crosslangvm.cpp +++ b/src/programs/crosslangvm.cpp @@ -6,12 +6,13 @@ using namespace Tesses::Framework; using namespace Tesses::CrossLang; using namespace Tesses::Framework::Filesystem; +static GC gc; int main(int argc, char** argv) { TF_InitWithConsole(); if(argc > 0) TF_AllowPortable(argv[0]); - GC gc; + gc.Start(); GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); @@ -26,4 +27,4 @@ int main(int argc, char** argv) if(GetObject(res,myi64)) return (int)myi64; return 0; -} \ No newline at end of file +} diff --git a/src/programs/slim.cpp b/src/programs/slim.cpp index 29a8c4e..6c4c6ab 100644 --- a/src/programs/slim.cpp +++ b/src/programs/slim.cpp @@ -7,7 +7,7 @@ using namespace Tesses::Framework::Filesystem; int main(int argc, char** argv) { //crosslang crossint - //crosslang + //crosslang //crosslang ... std::string programName = "crosslang"; @@ -20,7 +20,7 @@ int main(int argc, char** argv) path.RemoveExtension(); programName = path.GetFileName(); } - + std::vector args(argc); for(int i = 0; i < argc; i++) args[i] = argv[i]; @@ -28,14 +28,17 @@ int main(int argc, char** argv) { GC gc; gc.Start(); + int64_t myi64=0; + { GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TStd::RegisterStd(&gc,env); auto res= Programs::CrossLangInterperter(ls, env, args); - int64_t myi64; - if(GetObject(res,myi64)) - return (int)myi64; - return 0; + + GetObject(res,myi64); + + } + return (int)myi64; } else if(programName == "crossc") { @@ -73,31 +76,37 @@ int main(int argc, char** argv) { GC gc; gc.Start(); + int64_t myi64=0; + + { GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TStd::RegisterStd(&gc,env); auto res= Programs::CrossLangVM(ls, env, args); - int64_t myi64; - if(GetObject(res,myi64)) + GetObject(res,myi64); + } return (int)myi64; - return 0; + } else if(args.size() > 1) - { - + { + if(args[1] == "crossint") { + int64_t myi64=0; args.erase(args.begin()); GC gc; gc.Start(); + { GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TStd::RegisterStd(&gc,env); auto res= Programs::CrossLangInterperter(ls, env, args); - int64_t myi64; - if(GetObject(res,myi64)) - return (int)myi64; - return 0; + + GetObject(res,myi64); + } + return (int)myi64; + } else if(args[1] == "crossc") { @@ -136,29 +145,36 @@ int main(int argc, char** argv) } else if(args[1] == "crossvm") { + int64_t myi64=0; + args.erase(args.begin()); GC gc; + gc.Start(); + { GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TStd::RegisterStd(&gc,env); auto res= Programs::CrossLangVM(ls, env, args); - int64_t myi64; - if(GetObject(res,myi64)) - return (int)myi64; - return 0; + GetObject(res,myi64); + } + + return (int)myi64; } } - - + { + int64_t myi64=0; GC gc; + gc.Start(); - GCList ls(gc); - auto res= Programs::CrossLangShell(ls, args); - int64_t myi64; - if(GetObject(res,myi64)) - return (int)myi64; - return 0; - return 0; - -} \ No newline at end of file + { + GCList ls(gc); + auto res= Programs::CrossLangShell(ls, args); + + GetObject(res,myi64); + + + } + return (int)myi64; + } +} diff --git a/src/runtime_methods/std.cpp b/src/runtime_methods/std.cpp index 08951e3..41b036a 100644 --- a/src/runtime_methods/std.cpp +++ b/src/runtime_methods/std.cpp @@ -641,10 +641,7 @@ namespace Tesses::CrossLang } return nullptr; } - static TObject New_MemoryFilesystem(GCList& ls, std::vector args) - { - return std::make_shared(); - } + static TObject New_Filesystem(GCList& ls, std::vector args) { @@ -1329,9 +1326,7 @@ namespace Tesses::CrossLang newTypes->DeclareFunction(gc, "Filesystem","Create filesystem", {"fs"},New_Filesystem); newTypes->DeclareFunction(gc, "TempFS","Create a temp directory",{"",""}, New_TempFS); newTypes->DeclareFunction(gc, "Stream","Create stream", {"strm"},New_Stream); - - newTypes->DeclareFunction(gc, "MemoryFilesystem","Create in memory filesystem", {},New_MemoryFilesystem); - + newTypes->DeclareFunction(gc,"Version","Create a version object",{"$major","$minor","$patch","$build","$stage"},[](GCList& ls, std::vector args)->TObject{ int64_t major=1; diff --git a/src/types/vfsheapobject.cpp b/src/types/vfsheapobject.cpp index cf33594..6cfb3b4 100644 --- a/src/types/vfsheapobject.cpp +++ b/src/types/vfsheapobject.cpp @@ -7,130 +7,23 @@ namespace Tesses::CrossLang { this->ls = new GCList(gc); this->ls->Add(obj); this->obj = obj; - TDictionary* dict; - if(GetObjectHeap(obj,dict)) - { - gc->BarrierBegin(); - if(!dict->HasValue("OpenFile")) - { - dict->DeclareFunction(gc,"OpenFile","Open a file",{"path","mode"}, [](GCList& ls, std::vector args)->TObject { - return nullptr; - }); - } - if(!dict->HasValue("EnumeratePaths")) - { - dict->DeclareFunction(gc,"EnumeratePaths","Enumerate paths",{"path"}, [](GCList& ls, std::vector args)->TObject { - return TVFSPathEnumerator::Create(ls,Tesses::Framework::Filesystem::VFSPathEnumerator()); - }); - } - if(!dict->HasValue("ReadLink")) - { - dict->DeclareFunction(gc,"ReadLink","Read a symlink",{"path"}, [](GCList& ls, std::vector args)->TObject { - return Tesses::Framework::Filesystem::VFSPath(); - }); - } - - if(!dict->HasValue("VFSPathToSystem")) - { - dict->DeclareFunction(gc,"VFSPathToSystem","Convert path to system",{"path"}, [](GCList& ls, std::vector args)->TObject { - Tesses::Framework::Filesystem::VFSPath path; - if(GetArgumentAsPath(args,0,path)) - { - return path.ToString(); - } - return "/"; - }); - } - if(!dict->HasValue("SystemToVFSPath")) - { - dict->DeclareFunction(gc,"SystemToVFSPath","Convert system to path",{"path"}, [](GCList& ls, std::vector args)->TObject { - std::string p; - if(GetArgument(args,0,p)) - { - return Tesses::Framework::Filesystem::VFSPath(p); - } - return Tesses::Framework::Filesystem::VFSPath(); - }); - } - if(!dict->HasValue("GetDate")) - { - dict->DeclareFunction(gc,"GetDate","Get date from file",{"path"}, [](GCList& ls, std::vector args)->TObject { - auto dict = TDictionary::Create(ls); - ls.GetGC()->BarrierBegin(); - dict->SetValue("LastWrite", (int64_t)time(NULL)); - dict->SetValue("LastAccess", (int64_t)time(NULL)); - ls.GetGC()->BarrierEnd(); - return dict; - }); - } - if(!dict->HasValue("RegularFileExists")) - { - dict->DeclareFunction(gc,"RegularFileExists","Regular file exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - if(!dict->HasValue("SymlinkExists")) - { - dict->DeclareFunction(gc,"SymlinkExists","Symlink exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - if(!dict->HasValue("CharacterDeviceExists")) - { - dict->DeclareFunction(gc,"CharacterDeviceExists","Character file exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - if(!dict->HasValue("BlockDeviceExists")) - { - dict->DeclareFunction(gc,"BlockDeviceExists","Block file exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - if(!dict->HasValue("SocketFileExists")) - { - dict->DeclareFunction(gc,"SocketFileExists","Socket file exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - - if(!dict->HasValue("FIFOFileExists")) - { - dict->DeclareFunction(gc,"FIFOFileExists","FIFO file exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - if(!dict->HasValue("FileExists")) - { - dict->DeclareFunction(gc,"FileExists","File exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - if(!dict->HasValue("SpecialFileExists")) - { - dict->DeclareFunction(gc,"SpecialFileExists","Special file exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - if(!dict->HasValue("DirectoryExists")) - { - dict->DeclareFunction(gc,"DirectoryExists","Directory exists",{"path"}, [](GCList& ls, std::vector args)->TObject { - - return false; - }); - } - gc->BarrierEnd(); - } + } + Tesses::Framework::Filesystem::FIFOCreationResult TObjectVFS::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path) + { + TDictionary* dict; + + if(GetObjectHeap(this->obj, dict)) + { + GCList ls(this->ls->GetGC()); + auto res = dict->CallMethod(ls, "CreateFIFO",{path}); + int64_t n=0; + if(GetObject(res, n)) return (Tesses::Framework::Filesystem::FIFOCreationResult)n; + } + return Tesses::Framework::Filesystem::FIFOCreationResult::UnknownError; + } + std::shared_ptr TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode) { TDictionary* dict; @@ -189,136 +82,7 @@ namespace Tesses::CrossLang { } } - bool TObjectVFS::RegularFileExists(Tesses::Framework::Filesystem::VFSPath path) - { - - TDictionary* dict; - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "RegularFileExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - - bool TObjectVFS::SymlinkExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "SymlinkExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - bool TObjectVFS::CharacterDeviceExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "CharacterDeviceExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - bool TObjectVFS::BlockDeviceExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "BlockDeviceExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - bool TObjectVFS::SocketFileExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "SocketFileExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - bool TObjectVFS::FIFOFileExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "FIFOFileExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - bool TObjectVFS::FileExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "FileExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - bool TObjectVFS::SpecialFileExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "SpecialFileExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - void TObjectVFS::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile) + void TObjectVFS::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile) { TDictionary* dict; @@ -340,22 +104,7 @@ namespace Tesses::CrossLang { } } - bool TObjectVFS::DirectoryExists(Tesses::Framework::Filesystem::VFSPath path) - { - TDictionary* dict; - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "DirectoryExists",{path}); - bool out; - if(GetObject(res,out)) - { - return out; - } - } - return false; - } - void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path) + void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path) { TDictionary* dict; @@ -484,31 +233,6 @@ namespace Tesses::CrossLang { } return Tesses::Framework::Filesystem::VFSPath(); } - void TObjectVFS::GetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime& lastWrite, Tesses::Framework::Date::DateTime& lastAccess) - { - - TDictionary* dict; - if(GetObjectHeap(this->obj, dict)) - { - GCList ls(this->ls->GetGC()); - auto res = dict->CallMethod(ls, "GetDate",{path}); - if(GetObjectHeap(res,dict)) - { - this->ls->GetGC()->BarrierBegin(); - res = dict->GetValue("LastWrite"); - std::shared_ptr d; - if(GetObject(res,d)) - lastWrite =*d; - - res = dict->GetValue("LastAccess"); - - if(GetObject(res,d)) - lastWrite = *d; - - this->ls->GetGC()->BarrierEnd(); - } - } - } void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime lastWrite, Tesses::Framework::Date::DateTime lastAccess) { @@ -532,6 +256,80 @@ namespace Tesses::CrossLang { } } + void TObjectVFS::Chown(Tesses::Framework::Filesystem::VFSPath path, uint32_t uid, uint32_t gid) + { + TDictionary* dict; + + if(GetObjectHeap(this->obj, dict)) + { + GCList ls(this->ls->GetGC()); + dict->CallMethod(ls, "Chown",{path,(int64_t)uid, (int64_t)gid}); + + } + } + bool TObjectVFS::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data) + { + TDictionary* dict; + + if(GetObjectHeap(this->obj, dict)) + { + GCList ls(this->ls->GetGC()); + auto res = dict->CallMethod(ls, "Stat",{path}); + int64_t _num; + TDictionary* _dict; + TObject _o; + if(GetObjectHeap(res,_dict)) + { + this->ls->GetGC()->BarrierBegin(); + _o = dict->GetValue("BlockSize"); + if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num; + + _o = dict->GetValue("BlockCount"); + if(GetObject(_o,_num)) data.BlockCount = (uint64_t)_num; + + _o = dict->GetValue("Device"); + if(GetObject(_o,_num)) data.Device = (uint64_t)_num; + + _o = dict->GetValue("DeviceId"); + if(GetObject(_o,_num)) data.DeviceId = (uint64_t)_num; + + _o = dict->GetValue("GroupId"); + if(GetObject(_o,_num)) data.GroupId = (uint32_t)_num; + + _o = dict->GetValue("HardLinks"); + if(GetObject(_o,_num)) data.HardLinks = (uint64_t)_num; + std::shared_ptr dt; + _o = dict->GetValue("LastAccess"); + if(GetObject(_o,dt)) data.LastAccess = dt ? *dt : Tesses::Framework::Date::DateTime(0); + + + _o = dict->GetValue("LastModified"); + if(GetObject(_o,dt)) data.LastModified = dt ? *dt : Tesses::Framework::Date::DateTime(0); + + + + _o = dict->GetValue("LastStatus"); + if(GetObject(_o,dt)) data.LastStatus = dt ? *dt : Tesses::Framework::Date::DateTime(0); + + + + _o = dict->GetValue("Mode"); + if(GetObject(_o,_num)) data.Mode = (uint32_t)_num; + + _o = dict->GetValue("Size"); + if(GetObject(_o,_num)) data.Size = (uint64_t)_num; + + _o = dict->GetValue("UserId"); + if(GetObject(_o,_num)) data.UserId = (uint32_t)_num; + + + this->ls->GetGC()->BarrierEnd(); + return true; + } + } + + return false; + } bool TObjectVFS::StatVFS(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatVFSData& data) { TDictionary* dict; diff --git a/src/vm/bc/executemethod2.cpp b/src/vm/bc/executemethod2.cpp index 6826dab..95b3d4f 100644 --- a/src/vm/bc/executemethod2.cpp +++ b/src/vm/bc/executemethod2.cpp @@ -1997,6 +1997,38 @@ namespace Tesses::CrossLang { cse.back()->Push(gc, nullptr); return false; } + if(key == "Stat") + { + Tesses::Framework::Filesystem::VFSPath path; + + if(GetArgumentAsPath(args,0,path)) + { + Tesses::Framework::Filesystem::StatData data; + if(vfs->Stat(path,data)) + { + cse.back()->Push(gc, TDictionary::Create(ls,{ + TDItem("BlockCount", (int64_t)data.BlockCount), + TDItem("BlockSize", (int64_t)data.BlockSize), + TDItem("Device", (int64_t)data.Device), + TDItem("DeviceId", (int64_t)data.DeviceId), + TDItem("GroupId", (int64_t)data.GroupId), + TDItem("HardLinks", (int64_t)data.HardLinks), + TDItem("Inode", (int64_t)data.Inode), + TDItem("LastAccess", std::make_shared(data.LastAccess)), + TDItem("LastModified", std::make_shared(data.LastModified)), + TDItem("LastStatus", std::make_shared(data.LastStatus)), + TDItem("Mode", (int64_t)data.Mode), + TDItem("Size", (int64_t)data.Size), + TDItem("UserId", (int64_t)data.UserId) + })); + return false; + } + } + + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "StatVFS") { Tesses::Framework::Filesystem::VFSPath path; diff --git a/src/vm/gc.cpp b/src/vm/gc.cpp index eefbdce..a3e0796 100644 --- a/src/vm/gc.cpp +++ b/src/vm/gc.cpp @@ -13,28 +13,23 @@ using namespace Tesses::Framework::Threading; using namespace std::chrono; namespace Tesses::CrossLang { - + bool GC::IsRunning() { - + bool run = this->running; - + return run; } GC::GC() { - this->tpool=new Tesses::Framework::Lazy([]()->Tesses::Framework::Threading::ThreadPool*{ - auto threads = Tesses::Framework::Threading::ThreadPool::GetNumberOfCores(); - if(threads < 4) threads=4; - return new Tesses::Framework::Threading::ThreadPool(threads); - },[](Tesses::Framework::Threading::ThreadPool* p)->void{delete p;}); } TDictionary* CreateThread(GCList& ls, TCallable* callable,bool detached) { TDictionary* dict = TDictionary::Create(ls); - + ThreadHandle* th = new ThreadHandle(); th->gc = ls.GetGC(); th->callable = callable; @@ -43,16 +38,16 @@ namespace Tesses::CrossLang th->detached=detached; ls.Add(th); ls.GetGC()->Watch(th); - + ls.GetGC()->BarrierBegin(); dict->SetValue("_internal", th); - + dict->DeclareFunction(ls.GetGC(),"Join","Join thread",{},[th](GCList& _ls, std::vector _args)-> TObject{ - - + + th->thrd->Join(); delete th->thrd; - + if(th->hasReturned) { _ls.GetGC()->BarrierBegin(); @@ -69,12 +64,12 @@ namespace Tesses::CrossLang _ls.GetGC()->BarrierEnd(); return Undefined(); }); - + dict->DeclareFunction(ls.GetGC(),"getFinished","Get whether thread has finished",{},[th](GCList& _ls, std::vector _args)-> TObject{ return (bool)(th->hasReturned==true); }); - - ls.GetGC()->BarrierEnd(); + + ls.GetGC()->BarrierEnd(); th->thrd =new Thread([th]()->void { GC* gc=th->gc; GCList ls(gc); @@ -83,7 +78,7 @@ namespace Tesses::CrossLang TObject cb = th->callable->Call(ls,{}); gc->BarrierBegin(); th->returnValue=cb; - gc->BarrierEnd(); + gc->BarrierEnd(); th->hasReturned=true; }); while(!th->hasInit); @@ -91,14 +86,20 @@ namespace Tesses::CrossLang } void GC::Start() { + + this->tpool=new Tesses::Framework::Lazy([]()->Tesses::Framework::Threading::ThreadPool*{ + auto threads = Tesses::Framework::Threading::ThreadPool::GetNumberOfCores(); + if(threads < 4) threads=4; + return new Tesses::Framework::Threading::ThreadPool(threads); + },[](Tesses::Framework::Threading::ThreadPool* p)->void{delete p;}); this->mtx=new Mutex(); this->running = true; this->thrd = new Thread([this]()->void { std::chrono::time_point last_frame, this_frame; - + this_frame = system_clock::now(); last_frame = this_frame; - + while(this->IsRunning()) { this_frame = system_clock::now(); @@ -108,7 +109,7 @@ namespace Tesses::CrossLang last_frame = this_frame; this->Collect(); - + } @@ -129,14 +130,14 @@ namespace Tesses::CrossLang void GC::BarrierBegin() { - + this->mtx->Lock(); } void GC::BarrierEnd() - { - + { + this->mtx->Unlock(); - + } void GC::Watch(TObject obj) { @@ -144,7 +145,7 @@ namespace Tesses::CrossLang { auto _item=std::get(obj).obj; this->BarrierBegin(); - + for(auto item : this->objects) { if(item == _item) { @@ -187,7 +188,7 @@ namespace Tesses::CrossLang { auto _item=std::get(obj).obj; this->BarrierBegin(); - + for(auto item : this->roots) { if(item == _item) { @@ -203,6 +204,7 @@ namespace Tesses::CrossLang { return this->tpool->GetValue(); } + void GC::UnsetRoot(TObject obj) { if(std::holds_alternative(obj)) @@ -224,14 +226,19 @@ namespace Tesses::CrossLang GC::~GC() { GC::BarrierBegin(); + this->roots.clear(); GC::BarrierEnd(); + + + this->running=false; this->thrd->Join(); delete this->thrd; for(auto item : objects) delete item; - delete this->mtx; + delete this->tpool; + delete this->mtx; } void GC::RegisterEverythingCallback(std::function cb) @@ -265,6 +272,6 @@ namespace Tesses::CrossLang } } this->BarrierEnd(); - + } }; diff --git a/src/vm/gclist.cpp b/src/vm/gclist.cpp index 49b9f63..860de3b 100644 --- a/src/vm/gclist.cpp +++ b/src/vm/gclist.cpp @@ -44,7 +44,7 @@ namespace Tesses::CrossLang { auto _item=std::get(obj).obj; this->gc->BarrierBegin(); - + for(auto item : this->items) { if(item == _item) { @@ -70,4 +70,4 @@ namespace Tesses::CrossLang this->gc->UnsetRoot(this); gc->BarrierEnd(); } -} \ No newline at end of file +}