From 9e3ff8373304c4a94ab652c12ba6f3c6fbdc5fde Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Thu, 4 Jun 2026 14:00:44 +0300 Subject: [PATCH 1/8] das-fmt: release Program pointer in destroy das-fmt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dasFormatter's file-scope static State retained a ProgramPtr after destroy(). The Program got torn down during C++ static destruction, where ~ptr_ref_count locks the global ref_count_mutex — already destroyed on macOS (cross-TU order) → EINVAL → abort. Releasing the Program in destroy() keeps daslang objects from outliving the runtime. --- utils/dasFormatter/formatter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/dasFormatter/formatter.cpp b/utils/dasFormatter/formatter.cpp index 5b50c535d2..c32e8dec0e 100644 --- a/utils/dasFormatter/formatter.cpp +++ b/utils/dasFormatter/formatter.cpp @@ -62,6 +62,7 @@ namespace das::format { state.last = {}; state.options = {}; state.content_ = {}; + state.program = nullptr; } void set_to(Pos info) { From 6d53029e2995d46b90c6493932556910738474d7 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Tue, 2 Jun 2026 22:38:48 +0300 Subject: [PATCH 2/8] ast: move setRefSp out of simulate --- src/ast/ast_allocate_stack.cpp | 130 +++++++++++++++++++++++++++++++++ src/ast/ast_simulate.cpp | 129 -------------------------------- 2 files changed, 130 insertions(+), 129 deletions(-) diff --git a/src/ast/ast_allocate_stack.cpp b/src/ast/ast_allocate_stack.cpp index 855389033b..e6772ed0c0 100644 --- a/src/ast/ast_allocate_stack.cpp +++ b/src/ast/ast_allocate_stack.cpp @@ -5,6 +5,136 @@ namespace das { + // make tuple + + void ExprMakeTuple::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { + ExprMakeLocal::setRefSp(ref, cmres, sp, off); + int total = int(values.size()); + for ( int index=0; index != total; ++index ) { + auto & val = values[index]; + if ( val->rtti_isMakeLocal() ) { + uint32_t offset = extraOffset + makeType->getTupleFieldOffset(index); + auto mkl = static_cast(val); + mkl->setRefSp(ref, cmres, sp, offset); + } else if ( val->rtti_isCall() ) { + auto cll = static_cast(val); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } else if ( val->rtti_isInvoke() ) { + auto cll = static_cast(val); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } + } + } + // make array + + void ExprMakeArray::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { + ExprMakeLocal::setRefSp(ref, cmres, sp, off); + int total = int(values.size()); + uint32_t stride = recordType->getSizeOf(); + for ( int index=0; index != total; ++index ) { + auto & val = values[index]; + if ( val->rtti_isMakeLocal() ) { + uint32_t offset = extraOffset + index*stride; + auto mkl = static_cast(val); + mkl->setRefSp(ref, cmres, sp, offset); + } else if ( val->rtti_isCall() ) { + auto cll = static_cast(val); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } else if ( val->rtti_isInvoke() ) { + auto cll = static_cast(val); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } + } + } + + // structure + + void ExprMakeStruct::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { + ExprMakeLocal::setRefSp(ref, cmres, sp, off); + auto mkBaseT = makeType; // element view - makeType may be a fixed-array chain + while ( mkBaseT->baseType==Type::tFixedArray && mkBaseT->firstType ) mkBaseT = mkBaseT->firstType; + // if it's a handle type, we can't reuse the make-local chain + if ( mkBaseT->baseType == Type::tHandle ) return; + // we go through all fields, and if its [[ ]] field + // we tell it to piggy-back on our current sp, with appropriate offset + int total = int(structs.size()); + int stride = makeType->getStride(); + for ( int index=0; index != total; ++index ) { + auto & fields = structs[index]; + for ( const auto & decl : *fields ) { + auto field = mkBaseT->structType->findField(decl->name); + DAS_ASSERT(field && "should have failed in type infer otherwise"); + if ( decl->value->rtti_isMakeLocal() ) { + uint32_t offset = extraOffset + index*stride + field->offset; + auto mkl = static_cast(decl->value); + mkl->setRefSp(ref, cmres, sp, offset); + } else if ( decl->value->rtti_isCall() ) { + auto cll = static_cast(decl->value); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } else if ( decl->value->rtti_isInvoke() ) { + auto cll = static_cast(decl->value); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } + } + } + } + + + void ExprMakeLocal::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { + useStackRef = ref; + useCMRES = cmres; + doesNotNeedSp = true; + doesNotNeedInit = true; + stackTop = sp; + extraOffset = off; + } + + // variant + + void ExprMakeVariant::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { + ExprMakeLocal::setRefSp(ref, cmres, sp, off); + auto mkBaseT = makeType; // element view - makeType may be a fixed-array chain + while ( mkBaseT->baseType==Type::tFixedArray && mkBaseT->firstType ) mkBaseT = mkBaseT->firstType; + int stride = makeType->getStride(); + // we go through all fields, and if its [[ ]] field + // we tell it to piggy-back on our current sp, with appropriate offset + int index = 0; + for ( const auto & decl : variants ) { + auto fieldVariant = mkBaseT->findArgumentIndex(decl->name); + DAS_ASSERT(fieldVariant!=-1 && "should have failed in type infer otherwise"); + if ( decl->value->rtti_isMakeLocal() ) { + auto fieldOffset = mkBaseT->getVariantFieldOffset(fieldVariant); + uint32_t offset = extraOffset + index*stride + fieldOffset; + auto mkl = static_cast(decl->value); + mkl->setRefSp(ref, cmres, sp, offset); + mkl->doesNotNeedInit = false; + } else if ( decl->value->rtti_isCall() ) { + auto cll = static_cast(decl->value); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } else if ( decl->value->rtti_isInvoke() ) { + auto cll = static_cast(decl->value); + if ( cll->allowCmresSkip() ) { + cll->doesNotNeedSp = true; + } + } + index++; + } + } + class VarCMRes : public Visitor { public: VarCMRes( const ProgramPtr & prog, bool everything ) { diff --git a/src/ast/ast_simulate.cpp b/src/ast/ast_simulate.cpp index 823d0b9b31..759b2c06f8 100644 --- a/src/ast/ast_simulate.cpp +++ b/src/ast/ast_simulate.cpp @@ -682,49 +682,6 @@ namespace das } } - void ExprMakeLocal::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { - useStackRef = ref; - useCMRES = cmres; - doesNotNeedSp = true; - doesNotNeedInit = true; - stackTop = sp; - extraOffset = off; - } - - // variant - - void ExprMakeVariant::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { - ExprMakeLocal::setRefSp(ref, cmres, sp, off); - auto mkBaseT = makeType; // element view - makeType may be a fixed-array chain - while ( mkBaseT->baseType==Type::tFixedArray && mkBaseT->firstType ) mkBaseT = mkBaseT->firstType; - int stride = makeType->getStride(); - // we go through all fields, and if its [[ ]] field - // we tell it to piggy-back on our current sp, with appropriate offset - int index = 0; - for ( const auto & decl : variants ) { - auto fieldVariant = mkBaseT->findArgumentIndex(decl->name); - DAS_ASSERT(fieldVariant!=-1 && "should have failed in type infer otherwise"); - if ( decl->value->rtti_isMakeLocal() ) { - auto fieldOffset = mkBaseT->getVariantFieldOffset(fieldVariant); - uint32_t offset = extraOffset + index*stride + fieldOffset; - auto mkl = static_cast(decl->value); - mkl->setRefSp(ref, cmres, sp, offset); - mkl->doesNotNeedInit = false; - } else if ( decl->value->rtti_isCall() ) { - auto cll = static_cast(decl->value); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } else if ( decl->value->rtti_isInvoke() ) { - auto cll = static_cast(decl->value); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } - index++; - } - } - vector SimulateVisitor::simulateExprMakeVariant(const ExprMakeVariant *mkv) { gc_guard gc_scope; vector simlist; @@ -820,42 +777,6 @@ namespace das return expr; } - // structure - - void ExprMakeStruct::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { - ExprMakeLocal::setRefSp(ref, cmres, sp, off); - auto mkBaseT = makeType; // element view - makeType may be a fixed-array chain - while ( mkBaseT->baseType==Type::tFixedArray && mkBaseT->firstType ) mkBaseT = mkBaseT->firstType; - // if it's a handle type, we can't reuse the make-local chain - if ( mkBaseT->baseType == Type::tHandle ) return; - // we go through all fields, and if its [[ ]] field - // we tell it to piggy-back on our current sp, with appropriate offset - int total = int(structs.size()); - int stride = makeType->getStride(); - for ( int index=0; index != total; ++index ) { - auto & fields = structs[index]; - for ( const auto & decl : *fields ) { - auto field = mkBaseT->structType->findField(decl->name); - DAS_ASSERT(field && "should have failed in type infer otherwise"); - if ( decl->value->rtti_isMakeLocal() ) { - uint32_t offset = extraOffset + index*stride + field->offset; - auto mkl = static_cast(decl->value); - mkl->setRefSp(ref, cmres, sp, offset); - } else if ( decl->value->rtti_isCall() ) { - auto cll = static_cast(decl->value); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } else if ( decl->value->rtti_isInvoke() ) { - auto cll = static_cast(decl->value); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } - } - } - } - vector SimulateVisitor::simulateExprMakeStruct(const ExprMakeStruct *mks) { gc_guard gc_scope; vector simlist; @@ -1065,31 +986,6 @@ namespace das return expr; } - // make array - - void ExprMakeArray::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { - ExprMakeLocal::setRefSp(ref, cmres, sp, off); - int total = int(values.size()); - uint32_t stride = recordType->getSizeOf(); - for ( int index=0; index != total; ++index ) { - auto & val = values[index]; - if ( val->rtti_isMakeLocal() ) { - uint32_t offset = extraOffset + index*stride; - auto mkl = static_cast(val); - mkl->setRefSp(ref, cmres, sp, offset); - } else if ( val->rtti_isCall() ) { - auto cll = static_cast(val); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } else if ( val->rtti_isInvoke() ) { - auto cll = static_cast(val); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } - } - } vector SimulateVisitor::simulateExprMakeArray(const ExprMakeArray *mka) { vector simlist; @@ -1168,31 +1064,6 @@ namespace das return expr; } - // make tuple - - void ExprMakeTuple::setRefSp ( bool ref, bool cmres, uint32_t sp, uint32_t off ) { - ExprMakeLocal::setRefSp(ref, cmres, sp, off); - int total = int(values.size()); - for ( int index=0; index != total; ++index ) { - auto & val = values[index]; - if ( val->rtti_isMakeLocal() ) { - uint32_t offset = extraOffset + makeType->getTupleFieldOffset(index); - auto mkl = static_cast(val); - mkl->setRefSp(ref, cmres, sp, offset); - } else if ( val->rtti_isCall() ) { - auto cll = static_cast(val); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } else if ( val->rtti_isInvoke() ) { - auto cll = static_cast(val); - if ( cll->allowCmresSkip() ) { - cll->doesNotNeedSp = true; - } - } - } - } - vector SimulateVisitor::simulateExprMakeTuple(const ExprMakeTuple *mkt) { vector simlist; // init with 0 From c5989ca1b0e8e88ac038db12df97f3784a0d7e3a Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 3 Jun 2026 01:03:07 +0300 Subject: [PATCH 3/8] build: move ast_infer_type* to compiler lib Move the 6 ast_infer_type*.cpp and src/parser from the runtime lib into the compiler lib. Continues series of pull request to keep minimal runtime library. --- CMakeLists.txt | 26 ++-- include/daScript/ast/ast.h | 18 ++- include/daScript/ast/ast_expressions.h | 6 +- include/daScript/ast/ast_generate.h | 74 +++++------ include/daScript/ast/ast_infer_type.h | 3 + include/daScript/ast/ast_typedecl.h | 6 +- include/daScript/ast/ast_visitor.h | 4 +- include/daScript/misc/uric.h | 4 +- src/ast/ast.cpp | 29 ----- src/ast/ast_handle.cpp | 44 ------- src/ast/ast_infer_type.cpp | 168 ++++++++++++++----------- src/ast/ast_infer_type_report.cpp | 47 ++++++- src/ast/ast_parse.cpp | 3 +- src/ast/ast_typedecl.cpp | 2 +- src/hal/performance_time.cpp | 6 +- utils/dasFormatter/fmt.h | 4 +- 16 files changed, 223 insertions(+), 221 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d216e40620..45f7f63276 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -741,19 +741,12 @@ src/ast/ast_dispatch.cpp src/ast/ast_interop.cpp src/ast/ast_tls.cpp src/ast/ast_visitor.cpp -src/ast/ast_generate.cpp src/ast/ast_simulate.cpp src/ast/ast_typedecl.cpp src/ast/ast_match.cpp src/ast/ast_module.cpp src/ast/ast_print.cpp src/ast/ast_program.cpp -src/ast/ast_infer_type.cpp -src/ast/ast_infer_type_report.cpp -src/ast/ast_infer_type_function.cpp -src/ast/ast_infer_type_helper.cpp -src/ast/ast_infer_type_op.cpp -src/ast/ast_infer_type_make.cpp src/ast/ast_lint.cpp src/ast/ast_allocate_stack.cpp src/ast/ast_derive_alias.cpp @@ -766,7 +759,6 @@ src/ast/ast_escape_analysis.cpp src/ast/ast_unused.cpp src/ast/ast_annotations.cpp src/ast/ast_export.cpp -src/ast/ast_parse.cpp src/ast/ast_validate.cpp src/ast/ast_debug_info_helper.cpp src/ast/ast_handle.cpp @@ -862,7 +854,6 @@ src/misc/handle_registry.cpp src/misc/free_list.cpp src/misc/alloc_tracker.cpp src/misc/alloc_tracker_fast_stack.cpp -src/misc/lexer_alloc_track.cpp src/misc/uric.cpp src/misc/format.cpp ) @@ -1094,16 +1085,27 @@ MACRO(SETUP_LIBDASCRIPT library shared_lib full_setup sources exports_def) ENDMACRO() SET(LIBDASCRIPT_RUNTIME_SRC - ${PARSER_GENERATED_SRC} - ${PARSER_SRC} ${VECMATH_SRC} ${AST_SRC} ${SIMULATE_SRC} ${BUILTIN_SRC} + ${VECMATH_SRC} ${AST_SRC} ${SIMULATE_SRC} ${BUILTIN_SRC} ${MISC_SRC} ${MAIN_SRC} - ${DAGOR_NOISE_SRC} ${DAS_HASH_MAP_SRC} ${FAST_FLOAT_SRC} ${DASCRIPT_FMT_SRC} + ${DAGOR_NOISE_SRC} ${DAS_HASH_MAP_SRC} ${FAST_FLOAT_SRC} ) SET(LIBDASCRIPT_COMPILER_SRC ${SIMULATE_FUSION_SRC} + ${PARSER_GENERATED_SRC} + ${PARSER_SRC} + ${DASCRIPT_FMT_SRC} + src/ast/ast_parse.cpp + src/misc/lexer_alloc_track.cpp src/misc/daScriptC.cpp src/builtin/modules.cpp + src/ast/ast_infer_type.cpp + src/ast/ast_infer_type_report.cpp + src/ast/ast_infer_type_function.cpp + src/ast/ast_infer_type_helper.cpp + src/ast/ast_infer_type_op.cpp + src/ast/ast_infer_type_make.cpp + src/ast/ast_generate.cpp ) # Eventually libDaScript_runtime will contain only minimal subset of sources diff --git a/include/daScript/ast/ast.h b/include/daScript/ast/ast.h index c2b5f0d8aa..b82e680ea1 100644 --- a/include/daScript/ast/ast.h +++ b/include/daScript/ast/ast.h @@ -74,8 +74,8 @@ namespace das typedef AnnotationDeclaration * AnnotationDeclarationPtr; enum class LogicAnnotationOp { And, Or, Xor, Not }; - AnnotationPtr newLogicAnnotation ( LogicAnnotationOp op ); - AnnotationPtr newLogicAnnotation ( LogicAnnotationOp op, + DAS_API AnnotationPtr newLogicAnnotation ( LogicAnnotationOp op ); + DAS_API AnnotationPtr newLogicAnnotation ( LogicAnnotationOp op, const AnnotationDeclarationPtr & arg0, const AnnotationDeclarationPtr & arg1 ); @@ -640,7 +640,7 @@ namespace das Expression(const LineInfo & a) : at(a) { gc_magic = GC_MAGIC_EXPRESSION; } string describe() const; virtual ~Expression() {} - friend StringWriter& operator<< (StringWriter& stream, const Expression & func); + friend DAS_API StringWriter& operator<< (StringWriter& stream, const Expression & func); virtual ExpressionPtr visit(Visitor & /*vis*/ ) { DAS_ASSERT(0); return this; }; virtual ExpressionPtr clone( ExpressionPtr expr = nullptr ) const; static ExpressionPtr autoDereference ( ExpressionPtr expr ); @@ -744,8 +744,6 @@ namespace das return expr ? static_cast(expr) : new ExprType(); } - bool isLocalOrGlobal ( ExpressionPtr expr ); - #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4324) @@ -836,7 +834,7 @@ namespace das public: Function() { gc_magic = GC_MAGIC_FUNCTION; } virtual ~Function() {} - friend StringWriter& operator<< (StringWriter& stream, const Function & func); + friend DAS_API StringWriter& operator<< (StringWriter& stream, const Function & func); void getMangledName(TextWriter & ss) const; string getMangledName() const; uint64_t getMangledNameHash() const; @@ -1696,8 +1694,6 @@ namespace das bool patchAnnotations(); void fixupAnnotations(); void normalizeOptionTypes (); - void inferTypes(TextWriter & logs, ModuleGroup & libGroup); - void inferTypesDirty(TextWriter & logs, bool verbose); bool relocatePotentiallyUninitialized(TextWriter & logs); void lint (TextWriter & logs, ModuleGroup & libGroup ); void inferLint(TextWriter & logs); @@ -1823,13 +1819,13 @@ namespace das DAS_API Func adapt ( const char * funcName, char * pClass, const StructInfo * info ); // this one works for single module only - DAS_API ProgramPtr parseDaScript ( const string & fileName, const string & moduleName, const FileAccessPtr & access, + DAS_CC_API ProgramPtr parseDaScript ( const string & fileName, const string & moduleName, const FileAccessPtr & access, TextWriter & logs, ModuleGroup & libGroup, bool exportAll = false, bool isDep = false, CodeOfPolicies policies = CodeOfPolicies() ); // this one collectes dependencies and compiles with modules - DAS_API ProgramPtr compileDaScript ( const string & fileName, const FileAccessPtr & access, + DAS_CC_API ProgramPtr compileDaScript ( const string & fileName, const FileAccessPtr & access, TextWriter & logs, ModuleGroup & libGroup, CodeOfPolicies policies = CodeOfPolicies() ); - DAS_API ProgramPtr compileDaScriptSerialize ( const string & fileName, const FileAccessPtr & access, + DAS_CC_API ProgramPtr compileDaScriptSerialize ( const string & fileName, const FileAccessPtr & access, TextWriter & logs, ModuleGroup & libGroup, CodeOfPolicies policies = CodeOfPolicies() ); // collect script prerequisits diff --git a/include/daScript/ast/ast_expressions.h b/include/daScript/ast/ast_expressions.h index 1db8390920..8fa4991d3c 100644 --- a/include/daScript/ast/ast_expressions.h +++ b/include/daScript/ast/ast_expressions.h @@ -786,8 +786,8 @@ namespace das auto getValue() const { return ExprConstT::getValue(); }; }; - int64_t getConstExprIntOrUInt ( ExpressionPtr expr ); - pair tryGetConstExprIntOrUInt ( ExpressionPtr expr ); + DAS_API int64_t getConstExprIntOrUInt ( ExpressionPtr expr ); + DAS_API pair tryGetConstExprIntOrUInt ( ExpressionPtr expr ); struct DAS_API ExprConstUInt2 : ExprConstT { ExprConstUInt2(uint2 i = uint2()) @@ -1351,7 +1351,7 @@ namespace das struct MakeFieldDecl; typedef MakeFieldDecl * MakeFieldDeclPtr; - struct MakeFieldDecl : gc_node { + struct DAS_API MakeFieldDecl : gc_node { LineInfo at; string name; ExpressionPtr value = nullptr; diff --git a/include/daScript/ast/ast_generate.h b/include/daScript/ast/ast_generate.h index c50d0d13d7..4d9a587e65 100644 --- a/include/daScript/ast/ast_generate.h +++ b/include/daScript/ast/ast_generate.h @@ -21,15 +21,15 @@ namespace das { void assignDefaultArguments ( Function * func ); // puts all expression's subexpressions at new location - ExpressionPtr forceAt ( ExpressionPtr expr, const LineInfo & at ); - FunctionPtr forceAtFunction ( const FunctionPtr & func, const LineInfo & at ); + DAS_CC_API ExpressionPtr forceAt ( ExpressionPtr expr, const LineInfo & at ); + DAS_CC_API FunctionPtr forceAtFunction ( const FunctionPtr & func, const LineInfo & at ); // change generated flag for all subexpressions and variables - ExpressionPtr forceGenerated ( ExpressionPtr expr, bool setGenerated ); - FunctionPtr forceGeneratedFunction ( const FunctionPtr & expr, bool setGenerated ); + DAS_CC_API ExpressionPtr forceGenerated ( ExpressionPtr expr, bool setGenerated ); + DAS_CC_API FunctionPtr forceGeneratedFunction ( const FunctionPtr & expr, bool setGenerated ); // gives combined region for all subexpressions - LineInfo encloseAt ( ExpressionPtr expr ); + DAS_CC_API LineInfo encloseAt ( ExpressionPtr expr ); // replaces all occurrences of block argument name void renameBlockArgument ( ExprBlock * block, const string & name, const string & newName ); @@ -56,7 +56,7 @@ namespace das { with self ... */ - DAS_API void modifyToClassMember ( Function * func, Structure * baseClass, bool isExplicit, bool isConstant ); + DAS_CC_API void modifyToClassMember ( Function * func, Structure * baseClass, bool isExplicit, bool isConstant ); /* def Foo ( ... ) @@ -64,24 +64,24 @@ namespace das { Foo`Foo(self,...) return self */ - DAS_API FunctionPtr makeClassConstructor ( Structure * baseClass, Function * method ); + DAS_CC_API FunctionPtr makeClassConstructor ( Structure * baseClass, Function * method ); /* __rtti : void? = typeinfo(rtti_classinfo type) */ - DAS_API void makeClassRtti ( Structure * baseClass ); + DAS_CC_API void makeClassRtti ( Structure * baseClass ); /* override def __finalize() delete self */ - DAS_API FunctionPtr makeClassFinalize ( Structure * baseClass ); + DAS_CC_API FunctionPtr makeClassFinalize ( Structure * baseClass ); /* def STRUCT_NAME return [[STRUCT_NAME field1=init1, field2=init2, ...]] */ - DAS_API FunctionPtr makeConstructor ( Structure * str, bool isPrivate ); + FunctionPtr makeConstructor ( Structure * str, bool isPrivate ); // Walk `cls`'s inheritance chain starting from cls->parent, return the closest // ancestor with a user-defined ctor (Klass`Klass not generated). Used by the @@ -89,7 +89,7 @@ namespace das { // user code) and by the lint (super(...) walk-up matches the same target). // Returns nullptr if `cls` isn't a class, has no parent, or no ancestor has a // user ctor. - DAS_API Structure * findChainCtorAncestor ( Structure * cls ); + DAS_CC_API Structure * findChainCtorAncestor ( Structure * cls ); // Finalizer twin of findChainCtorAncestor: closest ancestor with a user-defined // finalizer ("finalize" class method, not generated). Used by the generated @@ -103,7 +103,7 @@ namespace das { a.f2 := b.f2 ... */ - DAS_API FunctionPtr makeClone ( Structure * str ); + DAS_CC_API FunctionPtr makeClone ( Structure * str ); /* def clone(var a:tuple<...>; var b:tuple<...>) @@ -111,7 +111,7 @@ namespace das { a._1 := b._1 ... */ - DAS_API FunctionPtr makeCloneTuple(const LineInfo & at, const TypeDeclPtr & tupleType, bool fromConst); + FunctionPtr makeCloneTuple(const LineInfo & at, const TypeDeclPtr & tupleType, bool fromConst); /* def clone(var a:tuple<...>; var b:tuple<...>) @@ -121,23 +121,23 @@ namespace das { a._1 := b._1 ... */ - DAS_API FunctionPtr makeCloneVariant(const LineInfo & at, const TypeDeclPtr & variantType, bool fromConst); + FunctionPtr makeCloneVariant(const LineInfo & at, const TypeDeclPtr & variantType, bool fromConst); /* delete var */ - DAS_API ExpressionPtr makeDelete ( const VariablePtr & var ); + ExpressionPtr makeDelete ( const VariablePtr & var ); /* a->b(args) is short for invoke(a.b, a, args) */ struct ExprInvoke; - DAS_API ExprInvoke * makeInvokeMethod ( const LineInfo & at, Expression * a, const string & b ); + ExprInvoke * makeInvokeMethod ( const LineInfo & at, Expression * a, const string & b ); /* this is short for invoke(type.b, a, args) */ - DAS_API ExprInvoke * makeInvokeMethod ( const LineInfo & at, Structure * callStruct, Expression * a, const string & b ); + ExprInvoke * makeInvokeMethod ( const LineInfo & at, Structure * callStruct, Expression * a, const string & b ); /* pointer finalizer, i.e. @@ -147,7 +147,7 @@ namespace das { delete native THIS THIS = null */ - DAS_API FunctionPtr generatePointerFinalizer ( const TypeDeclPtr & ptrType, const LineInfo & at ); + FunctionPtr generatePointerFinalizer ( const TypeDeclPtr & ptrType, const LineInfo & at ); /* structure finalizer, i.e. @@ -157,7 +157,7 @@ namespace das { delete field2 memzero(THIS) */ - DAS_API FunctionPtr generateStructureFinalizer ( const StructurePtr & ls ); + FunctionPtr generateStructureFinalizer ( const StructurePtr & ls ); /* tuple finalizer, i.e. @@ -166,7 +166,7 @@ namespace das { delete _1 memzero(THIS) */ - DAS_API FunctionPtr generateTupleFinalizer(const LineInfo & at, const TypeDeclPtr & tupleType); + FunctionPtr generateTupleFinalizer(const LineInfo & at, const TypeDeclPtr & tupleType); /* variant finalizer, i.e. @@ -178,14 +178,14 @@ namespace das { .... memzero(THIS) */ - DAS_API FunctionPtr generateVariantFinalizer(const LineInfo & at, const TypeDeclPtr & variantType); + FunctionPtr generateVariantFinalizer(const LineInfo & at, const TypeDeclPtr & variantType); /* variant finalizer, i.e. def clone(dest:smart_ptr<...>; src : any-ptr<...> ) smart_ptr_clone(dest, src) */ - DAS_API FunctionPtr makeCloneSmartPtr ( const LineInfo & at, const TypeDeclPtr & left, const TypeDeclPtr & right ); + FunctionPtr makeCloneSmartPtr ( const LineInfo & at, const TypeDeclPtr & left, const TypeDeclPtr & right ); /* struct __lambda_at_line_xxx @@ -194,7 +194,7 @@ namespace das { capture_field_1 capture_field_2 */ - DAS_API StructurePtr generateLambdaStruct ( const string & lambdaName, ExprBlock * block, + StructurePtr generateLambdaStruct ( const string & lambdaName, ExprBlock * block, const safe_var_set & capt, const vector & capture, bool needYield = false ); /* @@ -208,7 +208,7 @@ namespace das { generator_jit = (1<<1), generator_nojit = (1<<2) }; - DAS_API FunctionPtr generateLambdaFunction ( const string & lambdaName, ExprBlock * block, + FunctionPtr generateLambdaFunction ( const string & lambdaName, ExprBlock * block, const StructurePtr & ls, const safe_var_set & capt, const vector & capture, uint32_t genFlags, Program * thisProgram ); @@ -216,7 +216,7 @@ namespace das { local function, i.e. def __localfunction_function_at_line_xxx(...block_args...) */ - DAS_API FunctionPtr generateLocalFunction ( const string & lambdaName, ExprBlock * block ); + FunctionPtr generateLocalFunction ( const string & lambdaName, ExprBlock * block ); /* lambda finalizer, i.e. @@ -224,7 +224,7 @@ namespace das { with THIS ...block_finally... */ - DAS_API FunctionPtr generateLambdaFinalizer ( const string & lambdaName, ExprBlock * block, + FunctionPtr generateLambdaFinalizer ( const string & lambdaName, ExprBlock * block, const StructurePtr & ls, Program * thisProgram ); /* @@ -233,7 +233,7 @@ namespace das { FINALIZER=@__lambda_finalier_at_line_xx; _ba1=ba1; ba2=ba2; ... ]] */ - DAS_API ExpressionPtr generateLambdaMakeStruct ( const StructurePtr & ls, const FunctionPtr & lf, const FunctionPtr & lff, + ExpressionPtr generateLambdaMakeStruct ( const StructurePtr & ls, const FunctionPtr & lf, const FunctionPtr & lff, const safe_var_set & capt, const vector & capture, const LineInfo & at, const LineInfo & captureAt, Program * thisProgram ); @@ -247,7 +247,7 @@ namespace das { return temp */ struct ExprArrayComprehension; - DAS_API ExpressionPtr generateComprehension ( ExprArrayComprehension * expr, bool tableSyntax ); + ExpressionPtr generateComprehension ( ExprArrayComprehension * expr, bool tableSyntax ); /* array comprehension [[ for x in src; x_expr; where x_expr ]] @@ -257,7 +257,7 @@ namespace das { yield subexpr return false */ - DAS_API ExpressionPtr generateComprehensionIterator ( ExprArrayComprehension * expr ); + ExpressionPtr generateComprehensionIterator ( ExprArrayComprehension * expr ); /* replace reference with pointer @@ -267,19 +267,19 @@ namespace das { ... deref(blah) */ - DAS_API void replaceRef2Ptr ( ExpressionPtr expr, const string & name ); + void replaceRef2Ptr ( ExpressionPtr expr, const string & name ); /* give variables in the scope of 'expr' block unique names only for the top-level block */ - DAS_API void giveBlockVariablesUniqueNames ( ExpressionPtr expr ); + void giveBlockVariablesUniqueNames ( ExpressionPtr expr ); /* replace break and continue of a particular loop with 'goto label bg' and 'goto label cg' accordingly */ - DAS_API void replaceBreakAndContinue ( Expression * expr, int32_t bg, int32_t cg ); + void replaceBreakAndContinue ( Expression * expr, int32_t bg, int32_t cg ); /* replace @@ -291,7 +291,7 @@ namespace das { label X */ struct ExprYield; - DAS_API ExpressionPtr generateYield( ExprYield * expr, const FunctionPtr & func ); + ExpressionPtr generateYield( ExprYield * expr, const FunctionPtr & func ); /* replace @@ -303,7 +303,7 @@ namespace das { if variable is & - swap to pointer */ struct ExprLet; - DAS_API ExpressionPtr replaceGeneratorLet ( ExprLet * expr, const FunctionPtr & func, ExprBlock * scope ); + ExpressionPtr replaceGeneratorLet ( ExprLet * expr, const FunctionPtr & func, ExprBlock * scope ); /* replace @@ -329,7 +329,7 @@ namespace das { */ struct ExprIfThenElse; - DAS_API ExpressionPtr replaceGeneratorIfThenElse ( ExprIfThenElse * expr, const FunctionPtr & func ); + ExpressionPtr replaceGeneratorIfThenElse ( ExprIfThenElse * expr, const FunctionPtr & func ); /* replace @@ -346,7 +346,7 @@ namespace das { finally */ struct ExprWhile; - DAS_API ExpressionPtr replaceGeneratorWhile ( ExprWhile * expr, const FunctionPtr & func ); + ExpressionPtr replaceGeneratorWhile ( ExprWhile * expr, const FunctionPtr & func ); /* replace @@ -369,6 +369,6 @@ namespace das { */ struct ExprFor; - DAS_API ExpressionPtr replaceGeneratorFor ( ExprFor * expr, const FunctionPtr & func ); + ExpressionPtr replaceGeneratorFor ( ExprFor * expr, const FunctionPtr & func ); } diff --git a/include/daScript/ast/ast_infer_type.h b/include/daScript/ast/ast_infer_type.h index e24c938275..f3d0641a8b 100644 --- a/include/daScript/ast/ast_infer_type.h +++ b/include/daScript/ast/ast_infer_type.h @@ -641,4 +641,7 @@ namespace das { virtual void preVisitArrayComprehensionWhere(ExprArrayComprehension *expr, Expression *where) override; virtual ExpressionPtr visit(ExprArrayComprehension *expr) override; }; + + void inferTypes ( Program * program, TextWriter & logs, ModuleGroup & libGroup ); + void inferTypesDirty ( Program * program, TextWriter & logs, bool verbose ); } diff --git a/include/daScript/ast/ast_typedecl.h b/include/daScript/ast/ast_typedecl.h index 2c1fbb8585..0794fd50af 100644 --- a/include/daScript/ast/ast_typedecl.h +++ b/include/daScript/ast/ast_typedecl.h @@ -308,7 +308,7 @@ namespace das { TypeDeclPtr option2 = nullptr; }; - void findMatchingOptions ( const TypeDeclPtr & type, vector & matching ); + DAS_API void findMatchingOptions ( const TypeDeclPtr & type, vector & matching ); template struct ToBasicType { enum { type = Type::none }; @@ -764,9 +764,9 @@ namespace das { das::TypeDeclPtr DAS_API makeHandleType(const das::ModuleLibrary & library, const char * typeName); - bool splitTypeName ( const string & name, string & moduleName, string & funcName ); + DAS_API bool splitTypeName ( const string & name, string & moduleName, string & funcName ); - bool isCircularType ( const TypeDeclPtr & type ); + DAS_API bool isCircularType ( const TypeDeclPtr & type ); bool hasImplicit ( const TypeDeclPtr & type ); bool isMatchingArgumentType ( const TypeDeclPtr & argType, const TypeDeclPtr & passType ); diff --git a/include/daScript/ast/ast_visitor.h b/include/daScript/ast/ast_visitor.h index 2806af408d..5245710ed9 100644 --- a/include/daScript/ast/ast_visitor.h +++ b/include/daScript/ast/ast_visitor.h @@ -308,7 +308,7 @@ namespace das { AstContext generateAstContext( const ProgramPtr & prog, Expression * expr ); - class PassVisitor : public Visitor { + class DAS_API PassVisitor : public Visitor { public: explicit PassVisitor(int32_t round) : round(round) {} using Visitor::preVisit; @@ -337,7 +337,7 @@ namespace das { Function * func = nullptr; }; - class FoldingVisitor : public PassVisitor { + class DAS_API FoldingVisitor : public PassVisitor { public: FoldingVisitor(const ProgramPtr & prog, int32_t round = 0) : PassVisitor(round), ctx(prog->getContextStackSize()), helper(ctx.debugInfo) { diff --git a/include/daScript/misc/uric.h b/include/daScript/misc/uric.h index 191314e36b..cb03eac0b0 100644 --- a/include/daScript/misc/uric.h +++ b/include/daScript/misc/uric.h @@ -1,5 +1,7 @@ #pragma once +#include "daScript/misc/platform.h" + #ifndef URI_STATIC_BUILD #define URI_STATIC_BUILD #endif @@ -24,7 +26,7 @@ namespace das { return storage.c_str(); } - class Uri { + class DAS_API Uri { public: Uri(); Uri(UriUriA && uriA); diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index b08a2c472f..468161bc2e 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -5,35 +5,6 @@ namespace das { - // local or global - - bool isLocalOrGlobal ( ExpressionPtr expr ) { - if ( expr->rtti_isVar() ) { - auto ev = static_cast(expr); - return ev->local || !(ev->argument || ev->block); - } else if ( expr->rtti_isAt() ) { - auto ea = static_cast(expr); - if ( ea->subexpr && ea->subexpr->type && ea->subexpr->type->baseType==Type::tFixedArray ) { - return isLocalOrGlobal(ea->subexpr); - } - } else if ( expr->rtti_isField() ) { - auto ef = static_cast(expr); - if ( ef->value && ef->value->type && (ef->value->type->baseType!=Type::tHandle || ef->value->type->isLocal()) ) { - return isLocalOrGlobal(ef->value); - } - } else if ( expr->rtti_isSwizzle() ) { - auto sw = static_cast(expr); - if ( sw->value ) { - return isLocalOrGlobal(sw->value); - } - } else if ( expr->rtti_isCallLikeExpr() ) { - if ( expr->type && expr->type->ref ) { - return true; - } - } - return false; - } - // AOT AotListBase * AotListBase::head = nullptr; diff --git a/src/ast/ast_handle.cpp b/src/ast/ast_handle.cpp index 42dc608f23..13954324b9 100644 --- a/src/ast/ast_handle.cpp +++ b/src/ast/ast_handle.cpp @@ -283,48 +283,4 @@ namespace das { },"*"); } - void reportTrait ( const TypeDeclPtr & type, const string & prefix, set & visited, const callable & report ) { - report(type, prefix); - if ( type->baseType==Type::tPointer ) { - // trait never propages via pointer - //if ( type->firstType ) reportTrait(type->firstType, prefix, visited, report); - } else if ( type->baseType==Type::tStructure ) { - if ( type->structType ) { - if ( visited.find(type->structType)!=visited.end() ) return; - visited.insert(type->structType); - for ( auto & fld : type->structType->fields ) { - reportTrait(fld.type, prefix+"."+fld.name, visited, report); - } - } - } else if ( type->baseType==Type::tTuple || type->baseType==Type::tVariant ) { - if ( type->argNames.size() ) { - int index = 0; - for ( auto & argN : type->argNames ) { - reportTrait(type->argTypes[index], prefix+"."+argN, visited, report); - index++; - } - } else if ( type->argTypes.size() ) { - for ( size_t i=0; i!=type->argTypes.size(); ++i ) { - reportTrait(type->argTypes[i], prefix+"."+to_string(i), visited, report); - } - } - } else if ( type->baseType==Type::tArray ) { - if ( type->firstType ) reportTrait(type->firstType, prefix+"[]", visited, report); - } else if ( type->baseType==Type::tTable ) { - if ( type->firstType ) reportTrait(type->firstType, prefix+".key", visited, report); - if ( type->secondType ) reportTrait(type->secondType, prefix+".value", visited, report); - } else if ( type->baseType==Type::tHandle ) { - if ( type->annotation->rtti_isBasicStructureAnnotation() ) { - auto sa = (BasicStructureAnnotation *)(type->annotation); - for ( auto & fld : sa->fields ) { - reportTrait((fld.second).decl, prefix+"."+fld.first, visited, report); - } - } - } - } - - void reportTrait ( const TypeDeclPtr & type, const string & prefix, const callable & report ) { - set visisted; - reportTrait(type, prefix, visisted, report); - } } diff --git a/src/ast/ast_infer_type.cpp b/src/ast/ast_infer_type.cpp index 7b4b6bcff9..2d9c0166b3 100644 --- a/src/ast/ast_infer_type.cpp +++ b/src/ast/ast_infer_type.cpp @@ -10,6 +10,34 @@ namespace das { + // local or global (only used by type inference) + static bool isLocalOrGlobal ( ExpressionPtr expr ) { + if ( expr->rtti_isVar() ) { + auto ev = static_cast(expr); + return ev->local || !(ev->argument || ev->block); + } else if ( expr->rtti_isAt() ) { + auto ea = static_cast(expr); + if ( ea->subexpr && ea->subexpr->type && ea->subexpr->type->baseType==Type::tFixedArray ) { + return isLocalOrGlobal(ea->subexpr); + } + } else if ( expr->rtti_isField() ) { + auto ef = static_cast(expr); + if ( ef->value && ef->value->type && (ef->value->type->baseType!=Type::tHandle || ef->value->type->isLocal()) ) { + return isLocalOrGlobal(ef->value); + } + } else if ( expr->rtti_isSwizzle() ) { + auto sw = static_cast(expr); + if ( sw->value ) { + return isLocalOrGlobal(sw->value); + } + } else if ( expr->rtti_isCallLikeExpr() ) { + if ( expr->type && expr->type->ref ) { + return true; + } + } + return false; + } + // in ast_handle of all places, due to reporting fields void reportTrait(const TypeDeclPtr &type, const string &prefix, const callable &report); @@ -5969,16 +5997,16 @@ namespace das { // try infer, if failed - no macros // run macros til any of them does work, then reinfer and restart (i.e. infer after each macro) - void Program::inferTypes(TextWriter &logs, ModuleGroup &libGroup) { - newLambdaIndex = 1; + void inferTypes(Program * program, TextWriter &logs, ModuleGroup &libGroup) { + program->newLambdaIndex = 1; // inferPassesUsed is NOT reset here — parseDaScript resets it once per module // before the restartInfer: loop, so multiple inferTypes legs accumulate properly. - inferTypesDirty(logs, false); + inferTypesDirty(program, logs, false); bool anyMacrosDidWork = false; bool anyMacrosFailedToInfer = false; int pass = 0; - int32_t maxInferPasses = options.getIntOption("max_infer_passes", policies.max_infer_passes); - if (failed()) + int32_t maxInferPasses = program->options.getIntOption("max_infer_passes", program->policies.max_infer_passes); + if (program->failed()) goto failed_to_infer; do { if (pass++ >= maxInferPasses) @@ -5986,19 +6014,19 @@ namespace das { anyMacrosDidWork = false; anyMacrosFailedToInfer = false; auto modMacro = [&](Module *mod) -> bool { // we run all macros for each module - if (thisModule->isVisibleDirectly(mod) && mod != thisModule.get()) { + if (program->thisModule->isVisibleDirectly(mod) && mod != program->thisModule.get()) { for (const auto &pm : mod->macros) { - bool anyWork = pm->apply(this, thisModule.get()); - if (failed()) { // if macro failed, we report it, and we are done - error("macro '" + mod->name + "::" + pm->name + "' failed", "", "", LineInfo(), CompilationError::runtime_macro); + bool anyWork = pm->apply(program, program->thisModule.get()); + if (program->failed()) { // if macro failed, we report it, and we are done + program->error("macro '" + mod->name + "::" + pm->name + "' failed", "", "", LineInfo(), CompilationError::runtime_macro); return false; } if (anyWork) { // if macro did anything, we done - reportingInferErrors = true; - inferTypesDirty(logs, true); - reportingInferErrors = false; - if (failed()) { // if it failed to infer types after, we report it - error("macro '" + mod->name + "::" + pm->name + "' failed to infer", "", "", LineInfo(), CompilationError::runtime_macro_infer); + program->reportingInferErrors = true; + inferTypesDirty(program, logs, true); + program->reportingInferErrors = false; + if (program->failed()) { // if it failed to infer types after, we report it + program->error("macro '" + mod->name + "::" + pm->name + "' failed to infer", "", "", LineInfo(), CompilationError::runtime_macro_infer); anyMacrosFailedToInfer = true; return false; } @@ -6010,85 +6038,85 @@ namespace das { return true; }; Module::foreach (modMacro); - if (failed()) + if (program->failed()) break; if (anyMacrosDidWork) continue; - if (relocatePotentiallyUninitialized(logs)) { + if (program->relocatePotentiallyUninitialized(logs)) { anyMacrosDidWork = true; - reportingInferErrors = true; - inferTypesDirty(logs, true); - reportingInferErrors = false; - if (failed()) { - error("internal compiler error: variable relocation infer to fail", "", "", LineInfo(), CompilationError::internal_relocate_infer); + program->reportingInferErrors = true; + inferTypesDirty(program, logs, true); + program->reportingInferErrors = false; + if (program->failed()) { + program->error("internal compiler error: variable relocation infer to fail", "", "", LineInfo(), CompilationError::internal_relocate_infer); } continue; } libGroup.foreach (modMacro, "*"); - if (inScopePodAnalysis(logs)) { + if (program->inScopePodAnalysis(logs)) { anyMacrosDidWork = true; - reportingInferErrors = true; - inferTypesDirty(logs, true); - reportingInferErrors = false; - if (failed()) { - error("internal compiler error: pod analysis infer to fail", "", "", LineInfo(), CompilationError::internal_pod_analysis_infer); + program->reportingInferErrors = true; + inferTypesDirty(program, logs, true); + program->reportingInferErrors = false; + if (program->failed()) { + program->error("internal compiler error: pod analysis infer to fail", "", "", LineInfo(), CompilationError::internal_pod_analysis_infer); } continue; } - escapeAnalysis(logs); // pure analysis: annotate Variable::does_not_escape (idempotent, no AST change) - if (scopeFreeOptimization(logs)) { + program->escapeAnalysis(logs); // pure analysis: annotate Variable::does_not_escape (idempotent, no AST change) + if (program->scopeFreeOptimization(logs)) { anyMacrosDidWork = true; - reportingInferErrors = true; - inferTypesDirty(logs, true); - reportingInferErrors = false; - if (failed()) { - error("internal compiler error: escape free optimization infer to fail", "", "", LineInfo(), CompilationError::internal_pod_analysis_infer); + program->reportingInferErrors = true; + inferTypesDirty(program, logs, true); + program->reportingInferErrors = false; + if (program->failed()) { + program->error("internal compiler error: escape free optimization infer to fail", "", "", LineInfo(), CompilationError::internal_pod_analysis_infer); } continue; } - } while (!failed() && anyMacrosDidWork); + } while (!program->failed() && anyMacrosDidWork); failed_to_infer:; - if (failed() && !anyMacrosFailedToInfer && !macroException) { - reportingInferErrors = true; - inferTypesDirty(logs, true); - reportingInferErrors = false; + if (program->failed() && !anyMacrosFailedToInfer && !program->macroException) { + program->reportingInferErrors = true; + inferTypesDirty(program, logs, true); + program->reportingInferErrors = false; } if (pass >= maxInferPasses) { - error("type inference exceeded maximum allowed number of passes (" + to_string(maxInferPasses) + ")\n" + program->error("type inference exceeded maximum allowed number of passes (" + to_string(maxInferPasses) + ")\n" "this is likely due to a macro continuously being applied", "", "", LineInfo(), CompilationError::exceeds_infer_passes); } } - void Program::inferTypesDirty(TextWriter &logs, bool verbose) { + void inferTypesDirty(Program * program, TextWriter &logs, bool verbose) { int pass = 0; - int32_t maxInferPasses = options.getIntOption("max_infer_passes", policies.max_infer_passes); - bool logInferPasses = options.getBoolOption("log_infer_passes", false); + int32_t maxInferPasses = program->options.getIntOption("max_infer_passes", program->policies.max_infer_passes); + bool logInferPasses = program->options.getBoolOption("log_infer_passes", false); if (logInferPasses) { logs << "INITIAL CODE:\n" - << *this; + << *program; } // Per-pass collect+swap: infer mints a lot of throwaway TypeDecls/Expressions. When a // pass grows the working root enough, collect the live tree into a fresh root and swap // it in (O(1)); the old root's dtor sweeps that pass's garbage. Fire when growth since // the last collect crosses a node threshold (~2 MB) OR a fraction of the live set. - bool gcInferCollect = options.getBoolOption("gc_infer_collect", policies.gc_infer_collect); - int32_t gcInferNodes = options.getIntOption("gc_infer_collect_nodes", policies.gc_infer_collect_nodes); - int32_t gcInferPct = options.getIntOption("gc_infer_collect_pct", policies.gc_infer_collect_pct); - bool gcInferLog = options.getBoolOption("log_gc_infer_collect", false); + bool gcInferCollect = program->options.getBoolOption("gc_infer_collect", program->policies.gc_infer_collect); + int32_t gcInferNodes = program->options.getIntOption("gc_infer_collect_nodes", program->policies.gc_infer_collect_nodes); + int32_t gcInferPct = program->options.getIntOption("gc_infer_collect_pct", program->policies.gc_infer_collect_pct); + bool gcInferLog = program->options.getBoolOption("log_gc_infer_collect", false); uint64_t gcLastCount = gc_root::gc_get_active_root()->gc_count; // Collect the module's working root into a fresh root and swap it in (O(1)); the old // root's dtor sweeps the garbage. Returns the live count. No-op outside the normal // compile flow (the active root must BE the module's root) so tool/macro re-infer is safe. auto gcCollectAndSwap = [&]() -> uint64_t { gc_root * cur = gc_root::gc_get_active_root(); - if ( cur != thisModule->module_gc_root.get() ) return gcLastCount; + if ( cur != program->thisModule->module_gc_root.get() ) return gcLastCount; auto fresh = make_unique(); - thisModule->gc_collect(cur, fresh.get()); // live cur -> fresh (fresh target: full walk, no early-out) + program->thisModule->gc_collect(cur, fresh.get()); // live cur -> fresh (fresh target: full walk, no early-out) gc_root * live = fresh.get(); gc_root::gc_get_active_root() = live; - thisModule->module_gc_root = das::move(fresh); // deletes cur -> sweeps the garbage + program->thisModule->module_gc_root = das::move(fresh); // deletes cur -> sweeps the garbage return live->gc_count; }; for (pass = 0; pass < maxInferPasses; ++pass) { @@ -6098,7 +6126,7 @@ namespace das { bool fire = grown >= uint64_t(gcInferNodes) || ( gcLastCount && grown * 100 >= gcLastCount * uint64_t(gcInferPct) ); if ( gcInferLog ) { - logs << "[gc-infer] " << thisModule->name << " pass " << pass + logs << "[gc-infer] " << program->thisModule->name << " pass " << pass << " live=" << curCount << " grown=" << grown << " (" << (gcLastCount ? grown * 100 / gcLastCount : 0) << "%)" << (fire ? " -> COLLECT" : "") << "\n"; @@ -6106,19 +6134,19 @@ namespace das { if ( fire ) gcLastCount = gcCollectAndSwap(); } - if (macroException) + if (program->macroException) break; - inferPassesUsed++; // count each body invocation; avoids undercount when loop breaks early (pass is 0-based) - failToCompile = false; - errors.clear(); - InferTypes context(this, &logs); + program->inferPassesUsed++; // count each body invocation; avoids undercount when loop breaks early (pass is 0-based) + program->failToCompile = false; + program->errors.clear(); + InferTypes context(program, &logs); context.verbose = verbose || logInferPasses; - visit(context); + program->visit(context); for (auto efn : context.extraFunctions) { - addFunction(efn); + program->addFunction(efn); } vector> refreshFunctions; - thisModule->functions.foreach_with_hash([&](auto fn, uint64_t hash) { + program->thisModule->functions.foreach_with_hash([&](auto fn, uint64_t hash) { auto mnh = fn->getMangledNameHash(); if ( hash != mnh ) { refreshFunctions.emplace_back(make_tuple(fn, hash, mnh)); @@ -6126,28 +6154,28 @@ namespace das { fn->notInferred(); } }); for (auto rfn : refreshFunctions) { - if (!thisModule->functions.refresh_key(get<1>(rfn), get<2>(rfn))) { - error("internal compiler error: failed to refresh '" + get<0>(rfn)->getMangledName() + "'", "", "", get<0>(rfn)->at, CompilationError::internal_function_refresh); + if (!program->thisModule->functions.refresh_key(get<1>(rfn), get<2>(rfn))) { + program->error("internal compiler error: failed to refresh '" + get<0>(rfn)->getMangledName() + "'", "", "", get<0>(rfn)->at, CompilationError::internal_function_refresh); goto failedIt; } } bool anyMacrosDidWork = false; auto modMacro = [&](Module *mod) -> bool { - if (thisModule->isVisibleDirectly(mod) && mod != thisModule.get()) { + if (program->thisModule->isVisibleDirectly(mod) && mod != program->thisModule.get()) { for (const auto &pm : mod->inferMacros) { - anyMacrosDidWork |= pm->apply(this, thisModule.get()); + anyMacrosDidWork |= pm->apply(program, program->thisModule.get()); } } return true; }; Module::foreach (modMacro); - library.foreach (modMacro, "*"); - inferLint(logs); + program->library.foreach (modMacro, "*"); + program->inferLint(logs); if (logInferPasses) { logs << "PASS " << pass << ":\n" - << *this; - sort(errors.begin(), errors.end()); - for (auto &err : errors) { + << *program; + sort(program->errors.begin(), program->errors.end()); + for (auto &err : program->errors) { logs << reportError(err.at, err.what, err.extra, err.fixme, err.cerr); } } @@ -6158,7 +6186,7 @@ namespace das { } failedIt:; if (pass == maxInferPasses) { - error("type inference exceeded maximum allowed number of passes (" + to_string(maxInferPasses) + ")\n" + program->error("type inference exceeded maximum allowed number of passes (" + to_string(maxInferPasses) + ")\n" "this is likely due to a loop in the type system", "", "", LineInfo(), CompilationError::exceeds_infer_passes); diff --git a/src/ast/ast_infer_type_report.cpp b/src/ast/ast_infer_type_report.cpp index 5c5a56a100..6f93a55424 100644 --- a/src/ast/ast_infer_type_report.cpp +++ b/src/ast/ast_infer_type_report.cpp @@ -2,13 +2,56 @@ #include "daScript/ast/ast.h" #include "daScript/ast/ast_generate.h" +#include "daScript/ast/ast_handle.h" #include "daScript/ast/ast_infer_type.h" #include "daScript/ast/ast_visitor.h" namespace das { - // in ast_handle of all places, due to reporting fields - void reportTrait(const TypeDeclPtr &type, const string &prefix, const callable &report); + void reportTrait ( const TypeDeclPtr & type, const string & prefix, set & visited, const callable & report ) { + report(type, prefix); + if ( type->baseType==Type::tPointer ) { + // trait never propages via pointer + //if ( type->firstType ) reportTrait(type->firstType, prefix, visited, report); + } else if ( type->baseType==Type::tStructure ) { + if ( type->structType ) { + if ( visited.find(type->structType)!=visited.end() ) return; + visited.insert(type->structType); + for ( auto & fld : type->structType->fields ) { + reportTrait(fld.type, prefix+"."+fld.name, visited, report); + } + } + } else if ( type->baseType==Type::tTuple || type->baseType==Type::tVariant ) { + if ( type->argNames.size() ) { + int index = 0; + for ( auto & argN : type->argNames ) { + reportTrait(type->argTypes[index], prefix+"."+argN, visited, report); + index++; + } + } else if ( type->argTypes.size() ) { + for ( size_t i=0; i!=type->argTypes.size(); ++i ) { + reportTrait(type->argTypes[i], prefix+"."+to_string(i), visited, report); + } + } + } else if ( type->baseType==Type::tArray ) { + if ( type->firstType ) reportTrait(type->firstType, prefix+"[]", visited, report); + } else if ( type->baseType==Type::tTable ) { + if ( type->firstType ) reportTrait(type->firstType, prefix+".key", visited, report); + if ( type->secondType ) reportTrait(type->secondType, prefix+".value", visited, report); + } else if ( type->baseType==Type::tHandle ) { + if ( type->annotation->rtti_isBasicStructureAnnotation() ) { + auto sa = (BasicStructureAnnotation *)(type->annotation); + for ( auto & fld : sa->fields ) { + reportTrait((fld.second).decl, prefix+"."+fld.first, visited, report); + } + } + } + } + + void reportTrait ( const TypeDeclPtr & type, const string & prefix, const callable & report ) { + set visited; + reportTrait(type, prefix, visited, report); + } string InferTypes::reportInferAliasErrors(const TypeDeclPtr &decl) const { if (!verbose) diff --git a/src/ast/ast_parse.cpp b/src/ast/ast_parse.cpp index 60036ec40e..5b9522a01f 100644 --- a/src/ast/ast_parse.cpp +++ b/src/ast/ast_parse.cpp @@ -1,6 +1,7 @@ #include "daScript/misc/platform.h" #include "daScript/ast/ast.h" +#include "daScript/ast/ast_infer_type.h" #include "daScript/ast/ast_serializer.h" #include "daScript/ast/ast_expressions.h" #include "daScript/ast/ast_gc_report.h" @@ -866,7 +867,7 @@ namespace das { restartInfer: { auto timeI = ref_time_ticks(); - program->inferTypes(logs, libGroup); + inferTypes(program.get(), logs, libGroup); if ( policies.macro_context_collect ) libGroup.collectMacroContexts(); uint64_t inferLegT = get_time_usec(timeI); myInferT += inferLegT; diff --git a/src/ast/ast_typedecl.cpp b/src/ast/ast_typedecl.cpp index c27ea2f558..1f9b0c5541 100644 --- a/src/ast/ast_typedecl.cpp +++ b/src/ast/ast_typedecl.cpp @@ -3732,7 +3732,7 @@ namespace das else return (char)('a'+(Ch-10)); } - string aotSuffixNameEx ( const string & funcName, const char * suffix ) { + DAS_API string aotSuffixNameEx ( const string & funcName, const char * suffix ) { string name; bool prefix = false; for ( char ch : funcName ) { diff --git a/src/hal/performance_time.cpp b/src/hal/performance_time.cpp index 867e584aa4..0d3772f358 100644 --- a/src/hal/performance_time.cpp +++ b/src/hal/performance_time.cpp @@ -79,7 +79,7 @@ extern "C" int64_t get_time_nsec ( int64_t reft ) { return ref_time_ticks() - reft; } -extern "C" int64_t ref_time_delta_to_usec ( int64_t ref ) { +extern "C" DAS_API int64_t ref_time_delta_to_usec ( int64_t ref ) { return ref / 1000LL; } @@ -106,7 +106,7 @@ extern "C" int64_t get_time_nsec ( int64_t reft ) { return ref_time_ticks() - reft; } -extern "C" int64_t ref_time_delta_to_usec ( int64_t ref ) { return ref / 1000LL; } +extern "C" DAS_API int64_t ref_time_delta_to_usec ( int64_t ref ) { return ref / 1000LL; } #else // osx @@ -125,6 +125,6 @@ extern "C" int64_t get_time_nsec ( int64_t reft ) { return ref_time_ticks() - reft; } -extern "C" int64_t ref_time_delta_to_usec ( int64_t ref ) { return ref / 1000LL; } +extern "C" DAS_API int64_t ref_time_delta_to_usec ( int64_t ref ) { return ref / 1000LL; } #endif diff --git a/utils/dasFormatter/fmt.h b/utils/dasFormatter/fmt.h index 326761f546..cea8afc995 100644 --- a/utils/dasFormatter/fmt.h +++ b/utils/dasFormatter/fmt.h @@ -18,11 +18,11 @@ namespace das::format { /** * Run formatter on single file and it's content */ - DAS_API Result transform_syntax(const string &filename, const string content, format::FormatOptions options = {}); + DAS_CC_API Result transform_syntax(const string &filename, const string content, format::FormatOptions options = {}); /** * Run formatter on following files * @return 0 if everything is fine */ - DAS_API int run(FormatOptions opt, const vector &files); + DAS_CC_API int run(FormatOptions opt, const vector &files); }; From 4480b172ffafa6267667a06253e51f8a612ae1f0 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 3 Jun 2026 02:00:50 +0300 Subject: [PATCH 4/8] build: move dyn_modules to compiler lib dyn_modules.cpp calls compileDaScript (compiler) and its only caller require_dynamic_modules is the exe/daScriptC, so it belongs in the compiler lib. Moving it removes one runtime->compiler edge. Export adjustments (macro matches where the symbol is defined): - DAS_CC_API on require_dynamic_modules (now compiler-defined, called from the exe main.cpp) - DAS_API on normalizeFileName (sysos) and retry_pending_dynamic_modules (module_builtin_fio), runtime symbols now called from compiler-side dyn_modules Note: this alone does not turn the macOS build green - compileDaScript and the other cross-lib symbols still have additional runtime callers (module_file_access, module_builtin_ast, ast_program, ...). macOS rejects those undefined dylib symbols where Linux defers them. Co-Authored-By: Claude Opus 4.8 --- CMakeLists.txt | 4 ++-- include/daScript/ast/dyn_modules.h | 2 +- include/daScript/misc/lexer_alloc_track.h | 5 ++++- include/daScript/misc/sysos.h | 2 +- src/ast/dyn_modules.cpp | 2 +- src/builtin/module_builtin_fio.cpp | 4 ++-- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45f7f63276..8aed39789c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -762,7 +762,6 @@ src/ast/ast_export.cpp src/ast/ast_validate.cpp src/ast/ast_debug_info_helper.cpp src/ast/ast_handle.cpp -src/ast/dyn_modules.cpp include/daScript/ast/compilation_errors.h include/daScript/ast/ast_typedecl.h include/daScript/ast/ast_typefactory.h @@ -854,6 +853,7 @@ src/misc/handle_registry.cpp src/misc/free_list.cpp src/misc/alloc_tracker.cpp src/misc/alloc_tracker_fast_stack.cpp +src/misc/lexer_alloc_track.cpp src/misc/uric.cpp src/misc/format.cpp ) @@ -1096,7 +1096,7 @@ SET(LIBDASCRIPT_COMPILER_SRC ${PARSER_SRC} ${DASCRIPT_FMT_SRC} src/ast/ast_parse.cpp - src/misc/lexer_alloc_track.cpp + src/ast/dyn_modules.cpp src/misc/daScriptC.cpp src/builtin/modules.cpp src/ast/ast_infer_type.cpp diff --git a/include/daScript/ast/dyn_modules.h b/include/daScript/ast/dyn_modules.h index d19de4a388..d032128eef 100644 --- a/include/daScript/ast/dyn_modules.h +++ b/include/daScript/ast/dyn_modules.h @@ -12,7 +12,7 @@ class TextWriter; // containing `.das_module`), bypassing the modules/ scan. Path basenames // shadow same-named entries in das_root and project_root. // During initialization process it calls `initialize` in files `.das_module`. -DAS_API bool require_dynamic_modules(smart_ptr file_access, +DAS_CC_API bool require_dynamic_modules(smart_ptr file_access, const string &das_root, const string &project_root, const vector &load_modules, diff --git a/include/daScript/misc/lexer_alloc_track.h b/include/daScript/misc/lexer_alloc_track.h index 4ea6209809..5ddf25fac3 100644 --- a/include/daScript/misc/lexer_alloc_track.h +++ b/include/daScript/misc/lexer_alloc_track.h @@ -14,7 +14,10 @@ namespace das { // all under one site). // Param is tokenText, not yytext — flex defines yytext as a macro. - void lexer_track_alloc(std::string *p, const char *tokenText) noexcept; + // lexer_track_alloc is called from the lexer (compiler lib), so it is + // DAS_API-exported from the runtime lib; the other two are runtime-only + // (alloc_tracker) and need no export. + DAS_API void lexer_track_alloc(std::string *p, const char *tokenText) noexcept; void lexer_track_free(std::string *p) noexcept; int dump_lexer_string_leaks(FILE *out) noexcept; diff --git a/include/daScript/misc/sysos.h b/include/daScript/misc/sysos.h index 64a4099dc4..9d6f4804a1 100644 --- a/include/daScript/misc/sysos.h +++ b/include/daScript/misc/sysos.h @@ -21,7 +21,7 @@ namespace das { DAS_API string getDasRoot ( void ); DAS_API void setDasRoot ( const string & dr ); - string normalizeFileName ( const char * fileName ); + DAS_API string normalizeFileName ( const char * fileName ); string get_prefix ( const string & req ); // blah.... \ foo.bar - returns blah.... string get_suffix ( const string & req ); // blah.... \ foo.bar - returns foo.bar diff --git a/src/ast/dyn_modules.cpp b/src/ast/dyn_modules.cpp index a9e8b605ff..ad151990ee 100644 --- a/src/ast/dyn_modules.cpp +++ b/src/ast/dyn_modules.cpp @@ -14,7 +14,7 @@ namespace das { // Defined in module_builtin_fio.cpp — re-attempts modules whose dlopen was // deferred during the folder scan (sibling-module dependency loaded out of order). -void retry_pending_dynamic_modules(); +DAS_API void retry_pending_dynamic_modules(); static constexpr const char *MODULE_SUFFIX = ".das_module"; static constexpr const char *INIT_NAME = "initialize"; diff --git a/src/builtin/module_builtin_fio.cpp b/src/builtin/module_builtin_fio.cpp index ceb78e3b00..859c407301 100644 --- a/src/builtin/module_builtin_fio.cpp +++ b/src/builtin/module_builtin_fio.cpp @@ -215,7 +215,7 @@ namespace das { bool builtin_rmdir_rec_ec ( const char * path, char * & error, Context * ctx, LineInfoArg * at ) GENERATE_IO_STUB_RET void * register_dynamic_module ( const char *, const char *, int, Context *, LineInfoArg * ) GENERATE_IO_STUB_RET void register_native_path ( const char *, const char *, const char *, Context *, LineInfoArg * ) GENERATE_IO_STUB - void retry_pending_dynamic_modules () GENERATE_IO_STUB + DAS_API void retry_pending_dynamic_modules () GENERATE_IO_STUB #undef GENERATE_IO_STUB #undef GENERATE_IO_STUB_RET @@ -1416,7 +1416,7 @@ namespace das { // in a prior pass now succeeds and may unblock others. Keep iterating while a // pass loads at least one; stop when a pass makes no progress (remaining // entries have genuinely-missing .so files — left silent, matching Quiet). - void retry_pending_dynamic_modules() { + DAS_API void retry_pending_dynamic_modules() { bool progress = true; while (progress && !g_pending_dynamic_modules.empty()) { progress = false; From 353f6db08e816d95854b71748d621e64426c9bc8 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 3 Jun 2026 02:08:57 +0300 Subject: [PATCH 5/8] ast: extract Program::optimize, folding, lint to compiler lib Move the optimization-pass orchestration off the Program class into a free function optimizeProgram(Program*, ...) in a new compiler source file src/ast/ast_optimize.cpp. Sole caller (ast_parse.cpp, compiler) updated to optimizeProgram(program.get(), ...). Move ast_const_folding, ast_block_folding, ast_unused and ast_lint into the compiler lib. Enabled by the prior optimizeProgram extraction: the optimization* methods are now called only from compiler-side optimizeProgram, and the PassVisitor/FoldingVisitor base (defined in ast_const_folding) plus all its subclasses (block_folding, unused, InferTypes) are now together in the compiler lib. --- CMakeLists.txt | 9 +-- include/daScript/ast/ast.h | 11 +++- include/daScript/ast/ast_generate.h | 2 +- include/daScript/ast/ast_typedecl.h | 2 +- include/daScript/ast/ast_visitor.h | 4 +- modules/dasUnitTest/test_handles.cpp | 2 +- src/ast/ast_lint.cpp | 2 +- src/ast/ast_optimize.cpp | 59 +++++++++++++++++++ src/ast/ast_parse.cpp | 19 +++++- src/ast/ast_program.cpp | 50 ---------------- src/builtin/module_builtin_rtti.cpp | 2 +- .../integration/cpp/19_class_adapters.cpp | 2 +- 12 files changed, 98 insertions(+), 66 deletions(-) create mode 100644 src/ast/ast_optimize.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8aed39789c..749c866515 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -747,16 +747,12 @@ src/ast/ast_match.cpp src/ast/ast_module.cpp src/ast/ast_print.cpp src/ast/ast_program.cpp -src/ast/ast_lint.cpp src/ast/ast_allocate_stack.cpp src/ast/ast_derive_alias.cpp -src/ast/ast_const_folding.cpp -src/ast/ast_block_folding.cpp src/ast/ast_gc_collect.cpp src/ast/ast_gc_report.cpp src/ast/ast_inscope_pod.cpp src/ast/ast_escape_analysis.cpp -src/ast/ast_unused.cpp src/ast/ast_annotations.cpp src/ast/ast_export.cpp src/ast/ast_validate.cpp @@ -1096,6 +1092,11 @@ SET(LIBDASCRIPT_COMPILER_SRC ${PARSER_SRC} ${DASCRIPT_FMT_SRC} src/ast/ast_parse.cpp + src/ast/ast_optimize.cpp + src/ast/ast_const_folding.cpp + src/ast/ast_block_folding.cpp + src/ast/ast_unused.cpp + src/ast/ast_lint.cpp src/ast/dyn_modules.cpp src/misc/daScriptC.cpp src/builtin/modules.cpp diff --git a/include/daScript/ast/ast.h b/include/daScript/ast/ast.h index b82e680ea1..824581da3b 100644 --- a/include/daScript/ast/ast.h +++ b/include/daScript/ast/ast.h @@ -1121,7 +1121,7 @@ namespace das verifyAll = 0xffffffff }; - bool isValidBuiltinName ( const string & name, bool canPunkt = false ); + DAS_API bool isValidBuiltinName ( const string & name, bool canPunkt = false ); class DAS_API Module { public: @@ -1167,7 +1167,7 @@ namespace das if ( objModule->visibleEverywhere ) return true; return requireModule.find(objModule) != requireModule.end(); } - bool compileBuiltinModule ( const string & name, const unsigned char * const str, unsigned int str_len );//will replace last symbol to 0 + friend bool compileBuiltinModule ( Module * module, const string & name, const unsigned char * const str, unsigned int str_len ); static Module * require ( const string & name ); static Module * requireEx ( const string & name, bool allowPromoted, const string & expectedFileName = string() ); static void Initialize(); @@ -1707,7 +1707,6 @@ namespace das void buildAccessFlags(TextWriter & logs); bool verifyAndFoldContracts(); void validateAst(); - void optimize(TextWriter & logs, ModuleGroup & libGroup); bool inScopePodAnalysis(TextWriter & logs); bool escapeAnalysis(TextWriter & logs); // pure analysis: sets Variable::does_not_escape bool scopeFreeOptimization(TextWriter & logs); // consumes the analysis result: emits scope-exit frees @@ -1828,6 +1827,12 @@ namespace das DAS_CC_API ProgramPtr compileDaScriptSerialize ( const string & fileName, const FileAccessPtr & access, TextWriter & logs, ModuleGroup & libGroup, CodeOfPolicies policies = CodeOfPolicies() ); + // optimization pass (compiler lib); runs after type inference + void optimizeProgram ( Program * program, TextWriter & logs, ModuleGroup & libGroup ); + + // compile an embedded builtin module's source into `module` (compiler lib) + DAS_CC_API bool compileBuiltinModule ( Module * module, const string & name, const unsigned char * const str, unsigned int str_len ); + // collect script prerequisits DAS_API bool getPrerequisits ( const string & fileName, const FileAccessPtr & access, diff --git a/include/daScript/ast/ast_generate.h b/include/daScript/ast/ast_generate.h index 4d9a587e65..6c76bba3b2 100644 --- a/include/daScript/ast/ast_generate.h +++ b/include/daScript/ast/ast_generate.h @@ -29,7 +29,7 @@ namespace das { DAS_CC_API FunctionPtr forceGeneratedFunction ( const FunctionPtr & expr, bool setGenerated ); // gives combined region for all subexpressions - DAS_CC_API LineInfo encloseAt ( ExpressionPtr expr ); + LineInfo encloseAt ( ExpressionPtr expr ); // replaces all occurrences of block argument name void renameBlockArgument ( ExprBlock * block, const string & name, const string & newName ); diff --git a/include/daScript/ast/ast_typedecl.h b/include/daScript/ast/ast_typedecl.h index 0794fd50af..63a935c967 100644 --- a/include/daScript/ast/ast_typedecl.h +++ b/include/daScript/ast/ast_typedecl.h @@ -767,7 +767,7 @@ namespace das { DAS_API bool splitTypeName ( const string & name, string & moduleName, string & funcName ); DAS_API bool isCircularType ( const TypeDeclPtr & type ); - bool hasImplicit ( const TypeDeclPtr & type ); + DAS_API bool hasImplicit ( const TypeDeclPtr & type ); bool isMatchingArgumentType ( const TypeDeclPtr & argType, const TypeDeclPtr & passType ); enum class CpptSubstitureRef { no, yes }; diff --git a/include/daScript/ast/ast_visitor.h b/include/daScript/ast/ast_visitor.h index 5245710ed9..2806af408d 100644 --- a/include/daScript/ast/ast_visitor.h +++ b/include/daScript/ast/ast_visitor.h @@ -308,7 +308,7 @@ namespace das { AstContext generateAstContext( const ProgramPtr & prog, Expression * expr ); - class DAS_API PassVisitor : public Visitor { + class PassVisitor : public Visitor { public: explicit PassVisitor(int32_t round) : round(round) {} using Visitor::preVisit; @@ -337,7 +337,7 @@ namespace das { Function * func = nullptr; }; - class DAS_API FoldingVisitor : public PassVisitor { + class FoldingVisitor : public PassVisitor { public: FoldingVisitor(const ProgramPtr & prog, int32_t round = 0) : PassVisitor(round), ctx(prog->getContextStackSize()), helper(ctx.debugInfo) { diff --git a/modules/dasUnitTest/test_handles.cpp b/modules/dasUnitTest/test_handles.cpp index 485c2a3c38..8c65105f04 100644 --- a/modules/dasUnitTest/test_handles.cpp +++ b/modules/dasUnitTest/test_handles.cpp @@ -723,7 +723,7 @@ ModuleAotType Module_UnitTest::aotRequire ( TextWriter & tw ) const { #include "unit_test.das.inc" bool Module_UnitTest::appendCompiledFunctions() { - return compileBuiltinModule("unit_test.das",unit_test_das, sizeof(unit_test_das)); + return compileBuiltinModule(this, "unit_test.das",unit_test_das, sizeof(unit_test_das)); } REGISTER_DYN_MODULE(Module_UnitTest, Module_UnitTest); diff --git a/src/ast/ast_lint.cpp b/src/ast/ast_lint.cpp index cfd0998941..c0a81cc211 100644 --- a/src/ast/ast_lint.cpp +++ b/src/ast/ast_lint.cpp @@ -1298,7 +1298,7 @@ namespace das { } } g_verifyOptionsOnStartup; - vector> getCodeOfPolicyOptions(); + DAS_API vector> getCodeOfPolicyOptions(); void Program::lint ( TextWriter & /*logs*/, ModuleGroup & libGroup ) { if (!options.getBoolOption("lint", !policies.no_lint)) { diff --git a/src/ast/ast_optimize.cpp b/src/ast/ast_optimize.cpp new file mode 100644 index 0000000000..6af9d24f6d --- /dev/null +++ b/src/ast/ast_optimize.cpp @@ -0,0 +1,59 @@ +#include "daScript/misc/platform.h" + +#include "daScript/ast/ast.h" +#include "daScript/ast/ast_expressions.h" +#include "daScript/ast/ast_visitor.h" + +namespace das { + + void optimizeProgram(Program * program, TextWriter & logs, ModuleGroup & libGroup) { + bool logOpt = program->options.getBoolOption("log_optimization",false); + bool logPass = program->options.getBoolOption("log_optimization_passes",false); + bool log = logOpt || logPass; + bool any, last; + int optimizationRound = 1; + if (log) { + logs << *program << "\n"; + } + do { + if ( log ) logs << "OPTIMIZE " << optimizationRound << ":\n"; if ( logPass ) logs << *program; + any = false; + last = program->optimizationRefFolding(optimizationRound); if ( program->failed() ) break; any |= last; + if ( log ) logs << "REF FOLDING: " << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *program; + last = program->optimizationUnused(logs, optimizationRound); if ( program->failed() ) break; any |= last; + if ( log ) logs << "REMOVE UNUSED:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *program; + last = program->optimizationConstFolding(optimizationRound); if ( program->failed() ) break; any |= last; + if ( log ) logs << "CONST FOLDING:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *program; + last = program->optimizationCondFolding(optimizationRound); if ( program->failed() ) break; any |= last; + if ( log ) logs << "COND FOLDING:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *program; + last = program->optimizationBlockFolding(optimizationRound); if ( program->failed() ) break; any |= last; + if ( log ) logs << "BLOCK FOLDING:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *program; + // this is here again for a reason + last = program->optimizationUnused(logs, optimizationRound); if ( program->failed() ) break; any |= last; + if ( log ) logs << "REMOVE UNUSED:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *program; + // now, user macros + last = false; + auto modMacro = [&](Module * mod) -> bool { // we run all macros for each module + if ( program->thisModule->isVisibleDirectly(mod) && mod!=program->thisModule.get() ) { + for ( const auto & pm : mod->optimizationMacros ) { + last |= pm->apply(program, program->thisModule.get()); + if ( program->failed() ) { // if macro failed, we report it, and we are done + program->error("optimization macro " + mod->name + "::" + pm->name + " failed", "","",LineInfo(), CompilationError::runtime_macro); + return false; + } + } + } + return true; + }; + Module::foreach(modMacro); + if ( program->failed() ) break; + any |= last; + libGroup.foreach(modMacro,"*"); + if ( program->failed() ) break; + any |= last; + if ( log ) logs << "MACROS:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *program; + optimizationRound++; + } while ( any ); + } + +} diff --git a/src/ast/ast_parse.cpp b/src/ast/ast_parse.cpp index 5b9522a01f..da1555cf74 100644 --- a/src/ast/ast_parse.cpp +++ b/src/ast/ast_parse.cpp @@ -28,6 +28,23 @@ int das2_yyparse(yyscan_t yyscanner); namespace das { + // defined in ast_module.cpp (runtime); appends a parsed builtin module's content + bool appendBuiltinModuleContent ( Module * target, ProgramPtr program, const string & modName ); + + bool compileBuiltinModule ( Module * module, const string & modName, const unsigned char * const str, unsigned int str_len ) { + TextWriter issues; + auto access = make_smart(); + auto fileInfo = make_unique((char *) str, uint32_t(str_len), false); + access->setFileInfo(modName, das::move(fileInfo)); + ModuleGroup dummyLibGroup; + auto program = parseDaScript(modName, "", access, issues, dummyLibGroup, true); + module->ownFileInfo = access->letGoOfFileInfo(modName); + DAS_ASSERTF(module->ownFileInfo,"something went wrong and FileInfo for builtin module can not be obtained"); + auto result = appendBuiltinModuleContent(module, program, modName); + program->thisModule->module_gc_root.gc_dump_to_thread_root(); + return result; + } + bool isUtf8Text ( const char * src, uint32_t length ) { if ( length>=3 ) { auto usrc = (const uint8_t *)src; @@ -894,7 +911,7 @@ namespace das { if (!program->failed()) { if (program->getOptimize()) { callCompilationCallback(moduleName, fileName, "optimize"); - program->optimize(logs,libGroup); + optimizeProgram(program.get(),logs,libGroup); } else { program->buildAccessFlags(logs); } diff --git a/src/ast/ast_program.cpp b/src/ast/ast_program.cpp index e7764bb719..5e2d9cf252 100644 --- a/src/ast/ast_program.cpp +++ b/src/ast/ast_program.cpp @@ -631,54 +631,4 @@ namespace das { return policies.profiler || options.getBoolOption("profiler",false); } - void Program::optimize(TextWriter & logs, ModuleGroup & libGroup) { - bool logOpt = options.getBoolOption("log_optimization",false); - bool logPass = options.getBoolOption("log_optimization_passes",false); - bool log = logOpt || logPass; - bool any, last; - int optimizationRound = 1; - if (log) { - logs << *this << "\n"; - } - do { - if ( log ) logs << "OPTIMIZE " << optimizationRound << ":\n"; if ( logPass ) logs << *this; - any = false; - last = optimizationRefFolding(optimizationRound); if ( failed() ) break; any |= last; - if ( log ) logs << "REF FOLDING: " << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *this; - last = optimizationUnused(logs, optimizationRound); if ( failed() ) break; any |= last; - if ( log ) logs << "REMOVE UNUSED:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *this; - last = optimizationConstFolding(optimizationRound); if ( failed() ) break; any |= last; - if ( log ) logs << "CONST FOLDING:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *this; - last = optimizationCondFolding(optimizationRound); if ( failed() ) break; any |= last; - if ( log ) logs << "COND FOLDING:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *this; - last = optimizationBlockFolding(optimizationRound); if ( failed() ) break; any |= last; - if ( log ) logs << "BLOCK FOLDING:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *this; - // this is here again for a reason - last = optimizationUnused(logs, optimizationRound); if ( failed() ) break; any |= last; - if ( log ) logs << "REMOVE UNUSED:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *this; - // now, user macros - last = false; - auto modMacro = [&](Module * mod) -> bool { // we run all macros for each module - if ( thisModule->isVisibleDirectly(mod) && mod!=thisModule.get() ) { - for ( const auto & pm : mod->optimizationMacros ) { - last |= pm->apply(this, thisModule.get()); - if ( failed() ) { // if macro failed, we report it, and we are done - error("optimization macro " + mod->name + "::" + pm->name + " failed", "","",LineInfo(), CompilationError::runtime_macro); - return false; - } - } - } - return true; - }; - Module::foreach(modMacro); - if ( failed() ) break; - any |= last; - libGroup.foreach(modMacro,"*"); - if ( failed() ) break; - any |= last; - if ( log ) logs << "MACROS:" << (last ? "optimized" : "nothing") << "\n"; if ( logPass ) logs << *this; - optimizationRound++; - } while ( any ); - } - } diff --git a/src/builtin/module_builtin_rtti.cpp b/src/builtin/module_builtin_rtti.cpp index c5ebf91f6f..79b9c379b0 100644 --- a/src/builtin/module_builtin_rtti.cpp +++ b/src/builtin/module_builtin_rtti.cpp @@ -972,7 +972,7 @@ namespace das { virtual bool isLocal() const override { return true; } }; - vector> getCodeOfPolicyOptions() { + DAS_API vector> getCodeOfPolicyOptions() { vector> options; Module dummyMod; ModuleLibrary dummy(&dummyMod); diff --git a/tutorials/integration/cpp/19_class_adapters.cpp b/tutorials/integration/cpp/19_class_adapters.cpp index 7c43a7a224..9743ad5519 100644 --- a/tutorials/integration/cpp/19_class_adapters.cpp +++ b/tutorials/integration/cpp/19_class_adapters.cpp @@ -147,7 +147,7 @@ class Module_Tutorial19 : public Module { // Compile the embedded module (the abstract class definition). // The XDD .inc file provides the byte array and its size. - compileBuiltinModule("class_adapters_module.das", + compileBuiltinModule(this, "class_adapters_module.das", class_adapters_module_das, sizeof(class_adapters_module_das)); } From 899c7b584fe13b3915ce2ef698a6776a68e0eb18 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 3 Jun 2026 15:34:36 +0300 Subject: [PATCH 6/8] build: move ast module to compiler lib; clean runtime/compiler split Move the ast-reflection module group (module_builtin_ast + serialize stays runtime, flags, annotations*, adapters) and module_builtin_network to the compiler lib. Relocate the compile-at-require path off the runtime lib: - compileBuiltinModule: ast_module.cpp -> ast_parse.cpp (compiler); appendBuiltinModuleContent un-static'd + DAS_API so it stays runtime - rtti_builtin_compile / _ex / _file + make_file_access: bindings and impls moved from the rtti module (runtime) to the ast module (compiler). These builtins now live in ast_core instead of rtti_core - ModuleFileAccess / FsFileAccess ctors take a pre-compiled Program instead of calling compileDaScript; the compile moves to the caller - get_file_access (the pak compiler) moved from HAL to ast_parse.cpp (compiler); the project-specific override stays in HAL, reached via the new get_project_specific_file_access() getter Export tags follow "macro matches defining lib": DAS_CC_API on compiler-defined symbols called from exe/runtime (compileBuiltinModule, get_file_access); DAS_API on runtime symbols now called from the moved compiler code (Server, getFunctionHash/getFunctionAotHash/getAotHashComment, generateAstContext, collectDependencies, getProjectSpecificFileAccess, appendBuiltinModuleContent). Result: zero runtime->compiler edges. libDaScriptDyn(_runtime) shared and the static daslang_static both link with 0 undefined. The runtime lib no longer depends on the compiler lib (one-way compiler->runtime), which also fixes the macOS dylib self-link and the static-archive circular dependency. API note: compile / compile_file / make_file_access are now in the ast_core module, not rtti_core. Callers reaching them via daslib/ast (or ast_boost) are unaffected; any script requiring only rtti for these needs require ast. Co-Authored-By: Claude Opus 4.8 --- CMakeLists.txt | 18 +- doc/reflections/das2rst.das | 1 + ...unction-ast-compile-0x97cb4ad1839fc0a.rst} | 0 ...nction-ast-compile-0xbea6fab989dcfbdf.rst} | 0 ...n-ast-compile_file-0x60781bcd3310a035.rst} | 0 ...t-make_file_access-0x3f72c00df56d8c61.rst} | 0 include/daScript/ast/ast.h | 8 +- include/daScript/ast/ast_visitor.h | 2 +- include/daScript/das_project_specific.h | 2 + include/daScript/misc/network.h | 4 +- include/daScript/simulate/aot_builtin_ast.h | 394 +++++++++--------- include/daScript/simulate/debug_info.h | 3 +- include/daScript/simulate/fs_file_info.h | 2 +- modules/dasLLVM/daslib/llvm_exe.das | 15 +- modules/dasLLVM/daslib/llvm_jit_run.das | 2 +- src/ast/ast_module.cpp | 16 +- src/ast/ast_parse.cpp | 29 +- src/builtin/module_builtin_ast.cpp | 140 +++++-- src/builtin/module_builtin_rtti.cpp | 131 ++---- src/builtin/module_file_access.cpp | 5 +- src/builtin/module_jit.cpp | 1 - src/hal/project_specific_file_info.cpp | 21 +- src/simulate/fs_file_info.cpp | 4 +- src/simulate/simulate_fn_hash.cpp | 2 +- tests/flatten/test_flatten_errors.das | 2 +- tests/gc/gc_typedecl.das | 4 +- tests/jit_tests/dll_cache.das | 6 +- tests/jit_tests/jit_exe.das | 23 +- tests/language/reflection.das | 40 +- tests/module_tests/test_modules.das | 2 +- tests/typer_errors/test_alias_message.das | 2 +- tutorials/integration/cpp/16_sandbox.cpp | 13 +- tutorials/language/44_compile_and_run.das | 2 +- utils/daspkg/package_runner.das | 1 + 34 files changed, 462 insertions(+), 433 deletions(-) rename doc/source/stdlib/handmade/{function-rtti-compile-0x97cb4ad1839fc0a.rst => function-ast-compile-0x97cb4ad1839fc0a.rst} (100%) rename doc/source/stdlib/handmade/{function-rtti-compile-0xbea6fab989dcfbdf.rst => function-ast-compile-0xbea6fab989dcfbdf.rst} (100%) rename doc/source/stdlib/handmade/{function-rtti-compile_file-0x60781bcd3310a035.rst => function-ast-compile_file-0x60781bcd3310a035.rst} (100%) rename doc/source/stdlib/handmade/{function-rtti-make_file_access-0x3f72c00df56d8c61.rst => function-ast-make_file_access-0x3f72c00df56d8c61.rst} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 749c866515..a7da5d09a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -789,23 +789,15 @@ src/builtin/module_builtin_vector_ctor.cpp src/builtin/module_builtin_array.cpp src/builtin/module_builtin_math.cpp src/builtin/module_builtin_string.cpp +src/builtin/module_builtin_ast_serialize.cpp src/builtin/module_builtin_rtti.h src/builtin/module_builtin_rtti.cpp -src/builtin/module_builtin_ast.cpp -src/builtin/module_builtin_ast_serialize.cpp -src/builtin/module_builtin_ast_flags.cpp -src/builtin/module_builtin_ast_annotations.cpp -src/builtin/module_builtin_ast_annotations_1.cpp -src/builtin/module_builtin_ast_annotations_2.cpp -src/builtin/module_builtin_ast_annotations_3.cpp -src/builtin/module_builtin_ast_adapters.cpp src/builtin/module_builtin_ast.h src/builtin/module_builtin_uriparser.h src/builtin/module_builtin_uriparser.cpp src/builtin/module_jit.cpp src/builtin/module_builtin_fio.cpp src/builtin/module_builtin_dasbind.cpp -src/builtin/module_builtin_network.cpp src/builtin/module_builtin_debugger.cpp src/builtin/module_builtin_jobque.cpp src/builtin/module_file_access.cpp @@ -1107,6 +1099,14 @@ SET(LIBDASCRIPT_COMPILER_SRC src/ast/ast_infer_type_op.cpp src/ast/ast_infer_type_make.cpp src/ast/ast_generate.cpp + src/builtin/module_builtin_ast.cpp + src/builtin/module_builtin_ast_flags.cpp + src/builtin/module_builtin_ast_annotations.cpp + src/builtin/module_builtin_ast_annotations_1.cpp + src/builtin/module_builtin_ast_annotations_2.cpp + src/builtin/module_builtin_ast_annotations_3.cpp + src/builtin/module_builtin_ast_adapters.cpp + src/builtin/module_builtin_network.cpp ) # Eventually libDaScript_runtime will contain only minimal subset of sources diff --git a/doc/reflections/das2rst.das b/doc/reflections/das2rst.das index a129a6a982..9a29b35b2b 100644 --- a/doc/reflections/das2rst.das +++ b/doc/reflections/das2rst.das @@ -333,6 +333,7 @@ def document_module_rtti(_root : string) { def document_module_ast(_root : string) { var mod = [get_module("ast_core"), find_module("ast")] var groups <- array( + group_by_regex("Compilation and file access", mod, %regex~(compile|compile_file|make_file_access)$%%), group_by_regex("Call generation", mod, %regex~(make_call)$%%), group_by_regex("Visitor pattern", mod, %regex~visit.*%%), group_by_regex("Expression generation", mod, %regex~(force_generated|get_expression_annotation|make_type_info_structure)%%), diff --git a/doc/source/stdlib/handmade/function-rtti-compile-0x97cb4ad1839fc0a.rst b/doc/source/stdlib/handmade/function-ast-compile-0x97cb4ad1839fc0a.rst similarity index 100% rename from doc/source/stdlib/handmade/function-rtti-compile-0x97cb4ad1839fc0a.rst rename to doc/source/stdlib/handmade/function-ast-compile-0x97cb4ad1839fc0a.rst diff --git a/doc/source/stdlib/handmade/function-rtti-compile-0xbea6fab989dcfbdf.rst b/doc/source/stdlib/handmade/function-ast-compile-0xbea6fab989dcfbdf.rst similarity index 100% rename from doc/source/stdlib/handmade/function-rtti-compile-0xbea6fab989dcfbdf.rst rename to doc/source/stdlib/handmade/function-ast-compile-0xbea6fab989dcfbdf.rst diff --git a/doc/source/stdlib/handmade/function-rtti-compile_file-0x60781bcd3310a035.rst b/doc/source/stdlib/handmade/function-ast-compile_file-0x60781bcd3310a035.rst similarity index 100% rename from doc/source/stdlib/handmade/function-rtti-compile_file-0x60781bcd3310a035.rst rename to doc/source/stdlib/handmade/function-ast-compile_file-0x60781bcd3310a035.rst diff --git a/doc/source/stdlib/handmade/function-rtti-make_file_access-0x3f72c00df56d8c61.rst b/doc/source/stdlib/handmade/function-ast-make_file_access-0x3f72c00df56d8c61.rst similarity index 100% rename from doc/source/stdlib/handmade/function-rtti-make_file_access-0x3f72c00df56d8c61.rst rename to doc/source/stdlib/handmade/function-ast-make_file_access-0x3f72c00df56d8c61.rst diff --git a/include/daScript/ast/ast.h b/include/daScript/ast/ast.h index 824581da3b..5d4934e428 100644 --- a/include/daScript/ast/ast.h +++ b/include/daScript/ast/ast.h @@ -1017,10 +1017,10 @@ namespace das }; - uint64_t getFunctionHash ( Function * fun, SimNode * node, Context * context ); + DAS_API uint64_t getFunctionHash ( Function * fun, SimNode * node, Context * context ); - uint64_t getFunctionAotHash ( Function * fun ); - string getAotHashComment ( const Function * fun ); + DAS_API uint64_t getFunctionAotHash ( Function * fun ); + DAS_API string getAotHashComment ( const Function * fun ); uint64_t getVariableListAotHash ( const vector & globs, uint64_t initHash ); class DAS_API BuiltInFunction : public Function { @@ -1167,7 +1167,7 @@ namespace das if ( objModule->visibleEverywhere ) return true; return requireModule.find(objModule) != requireModule.end(); } - friend bool compileBuiltinModule ( Module * module, const string & name, const unsigned char * const str, unsigned int str_len ); + friend DAS_CC_API bool compileBuiltinModule ( Module * module, const string & name, const unsigned char * const str, unsigned int str_len ); static Module * require ( const string & name ); static Module * requireEx ( const string & name, bool allowPromoted, const string & expectedFileName = string() ); static void Initialize(); diff --git a/include/daScript/ast/ast_visitor.h b/include/daScript/ast/ast_visitor.h index 2806af408d..56d27cd589 100644 --- a/include/daScript/ast/ast_visitor.h +++ b/include/daScript/ast/ast_visitor.h @@ -306,7 +306,7 @@ namespace das { vector with; }; - AstContext generateAstContext( const ProgramPtr & prog, Expression * expr ); + DAS_API AstContext generateAstContext( const ProgramPtr & prog, Expression * expr ); class PassVisitor : public Visitor { public: diff --git a/include/daScript/das_project_specific.h b/include/daScript/das_project_specific.h index 67bbd3826d..296850f60b 100644 --- a/include/daScript/das_project_specific.h +++ b/include/daScript/das_project_specific.h @@ -5,6 +5,8 @@ namespace das { typedef smart_ptr (* GetFileAccessFunc)(char * pak); void set_project_specific_fs_callbacks(GetFileAccessFunc getFileAccess); + // project-specific file-access override, consumed by get_file_access (compiler lib) + DAS_API GetFileAccessFunc get_project_specific_file_access(); class Context; diff --git a/include/daScript/misc/network.h b/include/daScript/misc/network.h index ff8fb85e45..9beb1d0d4b 100644 --- a/include/daScript/misc/network.h +++ b/include/daScript/misc/network.h @@ -1,5 +1,7 @@ #pragma once +#include "daScript/misc/platform.h" + namespace das { #ifdef _WIN32 #ifdef _WIN64 @@ -11,7 +13,7 @@ namespace das { typedef int socket_t; #endif - class Server { + class DAS_API Server { public: Server (); virtual ~Server(); diff --git a/include/daScript/simulate/aot_builtin_ast.h b/include/daScript/simulate/aot_builtin_ast.h index 2434aceced..2b1ee97fa1 100644 --- a/include/daScript/simulate/aot_builtin_ast.h +++ b/include/daScript/simulate/aot_builtin_ast.h @@ -6,23 +6,23 @@ #include "daScript/ast/ast_visitor.h" namespace das { - DAS_API char * ast_describe_typedecl ( TypeDecl * t, bool d_extra, bool d_contracts, bool d_module, Context * context, LineInfoArg * at ); - DAS_API char * ast_describe_typedecl_cpp ( TypeDecl * t, bool d_substitureRef, bool d_skipRef, bool d_skipConst, bool d_redundantConst, bool d_ChooseSmartPtr, Context * context, LineInfoArg * at ); - DAS_API char * ast_describe_expression ( Expression * t, Context * context, LineInfoArg * at ); - DAS_API char * ast_describe_function ( Function * t, Context * context, LineInfoArg * at ); - DAS_API char * ast_das_to_string ( Type bt, Context * context, LineInfoArg * at ); - DAS_API char * ast_find_bitfield_name ( TypeDecl * bft, Bitfield value, Context * context, LineInfoArg * at ); - DAS_API char * ast_find_enum_name ( Enumeration * enu, int64_t value, Context * context, LineInfoArg * at ); - DAS_API int64_t ast_find_enum_value ( EnumerationPtr enu, const char * value ); - DAS_API int64_t ast_find_enum_value_ex ( Enumeration * enu, const char * value ); + DAS_CC_API char * ast_describe_typedecl ( TypeDecl * t, bool d_extra, bool d_contracts, bool d_module, Context * context, LineInfoArg * at ); + DAS_CC_API char * ast_describe_typedecl_cpp ( TypeDecl * t, bool d_substitureRef, bool d_skipRef, bool d_skipConst, bool d_redundantConst, bool d_ChooseSmartPtr, Context * context, LineInfoArg * at ); + DAS_CC_API char * ast_describe_expression ( Expression * t, Context * context, LineInfoArg * at ); + DAS_CC_API char * ast_describe_function ( Function * t, Context * context, LineInfoArg * at ); + DAS_CC_API char * ast_das_to_string ( Type bt, Context * context, LineInfoArg * at ); + DAS_CC_API char * ast_find_bitfield_name ( TypeDecl * bft, Bitfield value, Context * context, LineInfoArg * at ); + DAS_CC_API char * ast_find_enum_name ( Enumeration * enu, int64_t value, Context * context, LineInfoArg * at ); + DAS_CC_API int64_t ast_find_enum_value ( EnumerationPtr enu, const char * value ); + DAS_CC_API int64_t ast_find_enum_value_ex ( Enumeration * enu, const char * value ); - DAS_API int32_t any_array_size ( void * _arr ); - DAS_API int32_t any_table_size ( void * _tab ); - DAS_API void any_array_foreach ( void * _arr, int stride, const TBlock & blk, Context * context, LineInfoArg * at ); - DAS_API void any_table_foreach ( void * _tab, int keyStride, int valueStride, const TBlock & blk, Context * context, LineInfoArg * at ); + DAS_CC_API int32_t any_array_size ( void * _arr ); + DAS_CC_API int32_t any_table_size ( void * _tab ); + DAS_CC_API void any_array_foreach ( void * _arr, int stride, const TBlock & blk, Context * context, LineInfoArg * at ); + DAS_CC_API void any_table_foreach ( void * _tab, int keyStride, int valueStride, const TBlock & blk, Context * context, LineInfoArg * at ); - DAS_API int32_t get_variant_field_offset ( TypeDecl * td, int32_t index, Context * context, LineInfoArg * at ); - DAS_API int32_t get_tuple_field_offset ( TypeDecl * td, int32_t index, Context * context, LineInfoArg * at ); + DAS_CC_API int32_t get_variant_field_offset ( TypeDecl * td, int32_t index, Context * context, LineInfoArg * at ); + DAS_CC_API int32_t get_tuple_field_offset ( TypeDecl * td, int32_t index, Context * context, LineInfoArg * at ); __forceinline void mks_vector_emplace ( MakeStruct & vec, MakeFieldDeclPtr value ) { vec.push_back(value); @@ -37,61 +37,61 @@ namespace das { vec.resize(newSize); } - DAS_API Module * compileModule ( Context * context, LineInfoArg * at ); - DAS_API smart_ptr_raw compileProgram ( Context * context, LineInfoArg * at ); + DAS_CC_API Module * compileModule ( Context * context, LineInfoArg * at ); + DAS_CC_API smart_ptr_raw compileProgram ( Context * context, LineInfoArg * at ); - DAS_API void aotSuffix( StructureAnnotation *structure, StructurePtr st, const AnnotationArgumentList & args, StringBuilderWriter *writer, Context * context, LineInfoArg * at); - DAS_API void aotMacroPrefix( TypeInfoMacro *macro, StringBuilderWriter *ss, ExpressionPtr expr); - DAS_API void aotMacroSuffix( TypeInfoMacro *macro, StringBuilderWriter *ss, ExpressionPtr expr); - DAS_API const char *getAotName(Function* func, ExprCallFunc *call, Context * context, LineInfoArg * at ); - DAS_API void aotBody( StructureAnnotation *structure, StructurePtr st, const AnnotationArgumentList & args, StringBuilderWriter *writer, Context * context, LineInfoArg * at); - DAS_API void aotPreVisitGetFieldPtr(TypeAnnotation *ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at); - DAS_API void aotPreVisitGetField(TypeAnnotation *ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at); - DAS_API void aotVisitGetField(TypeAnnotation *ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at); - DAS_API bool aotNeedTypeInfo(const TypeInfoMacro *macro, ExpressionPtr expr); - DAS_API void aotVisitGetFieldPtr( TypeAnnotation* ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at ); - DAS_API const char * getAotArgumentSuffix(Function* func, ExprCallFunc * call, int argIndex, Context * context, LineInfoArg * at ); - DAS_API const char * getAotArgumentPrefix(Function* func, ExprCallFunc * call, int argIndex, Context * context, LineInfoArg * at ); - DAS_API bool isAstSameType(TypeDecl * argType, TypeDecl * passType, bool refMatters, + DAS_CC_API void aotSuffix( StructureAnnotation *structure, StructurePtr st, const AnnotationArgumentList & args, StringBuilderWriter *writer, Context * context, LineInfoArg * at); + DAS_CC_API void aotMacroPrefix( TypeInfoMacro *macro, StringBuilderWriter *ss, ExpressionPtr expr); + DAS_CC_API void aotMacroSuffix( TypeInfoMacro *macro, StringBuilderWriter *ss, ExpressionPtr expr); + DAS_CC_API const char *getAotName(Function* func, ExprCallFunc *call, Context * context, LineInfoArg * at ); + DAS_CC_API void aotBody( StructureAnnotation *structure, StructurePtr st, const AnnotationArgumentList & args, StringBuilderWriter *writer, Context * context, LineInfoArg * at); + DAS_CC_API void aotPreVisitGetFieldPtr(TypeAnnotation *ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at); + DAS_CC_API void aotPreVisitGetField(TypeAnnotation *ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at); + DAS_CC_API void aotVisitGetField(TypeAnnotation *ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at); + DAS_CC_API bool aotNeedTypeInfo(const TypeInfoMacro *macro, ExpressionPtr expr); + DAS_CC_API void aotVisitGetFieldPtr( TypeAnnotation* ann, StringBuilderWriter *ss, const char *name, Context * context, LineInfoArg * at ); + DAS_CC_API const char * getAotArgumentSuffix(Function* func, ExprCallFunc * call, int argIndex, Context * context, LineInfoArg * at ); + DAS_CC_API const char * getAotArgumentPrefix(Function* func, ExprCallFunc * call, int argIndex, Context * context, LineInfoArg * at ); + DAS_CC_API bool isAstSameType(TypeDecl * argType, TypeDecl * passType, bool refMatters, bool constMatters, bool temporaryMatters, bool allowSubstitute, Context * context, LineInfoArg * at ); - DAS_API void aotFuncPrefix(FunctionAnnotation* ann, StringBuilderWriter * stg, ExprCallFunc *call, Context * context, LineInfoArg * at ); - DAS_API void aotStructPrefix(StructureAnnotation* ann, Structure *structure, const AnnotationArgumentList &args, + DAS_CC_API void aotFuncPrefix(FunctionAnnotation* ann, StringBuilderWriter * stg, ExprCallFunc *call, Context * context, LineInfoArg * at ); + DAS_CC_API void aotStructPrefix(StructureAnnotation* ann, Structure *structure, const AnnotationArgumentList &args, StringBuilderWriter * stg, Context * context, LineInfoArg * at ); - DAS_API const char * stringBuilderStr(StringBuilderWriter *ss, Context * context, LineInfoArg * at); - DAS_API void stringBuilderClear(StringBuilderWriter *ss); + DAS_CC_API const char * stringBuilderStr(StringBuilderWriter *ss, Context * context, LineInfoArg * at); + DAS_CC_API void stringBuilderClear(StringBuilderWriter *ss); - DAS_API const Structure * findFieldParent( Structure * structure, const char *name, Context * context, LineInfoArg * at ); - DAS_API TypeDeclPtr makeBlockType(ExprBlock *blk); + DAS_CC_API const Structure * findFieldParent( Structure * structure, const char *name, Context * context, LineInfoArg * at ); + DAS_CC_API TypeDeclPtr makeBlockType(ExprBlock *blk); // Note: it will be removed once DebugInfoHelper rewritten in das - DAS_API TypeInfo * makeTypeInfo ( DebugInfoHelper * helper, TypeInfo * info, const TypeDeclPtr & type ); - DAS_API VarInfo * makeVariableDebugInfo ( DebugInfoHelper * helper, Variable *var ); - DAS_API VarInfo * makeStructVariableDebugInfo ( DebugInfoHelper * helper, const Structure * st, const Structure::FieldDeclaration * var ); - DAS_API StructInfo * makeStructureDebugInfo ( DebugInfoHelper * helper, const Structure * st ); - DAS_API FuncInfo * makeFunctionDebugInfo ( DebugInfoHelper * helper, const Function * fn ); - DAS_API EnumInfo * makeEnumDebugInfo ( DebugInfoHelper * helper, const Enumeration * en ); - DAS_API FuncInfo * makeInvokeableTypeDebugInfo ( DebugInfoHelper * helper, TypeDeclPtr blk, const LineInfo & at ); + DAS_CC_API TypeInfo * makeTypeInfo ( DebugInfoHelper * helper, TypeInfo * info, const TypeDeclPtr & type ); + DAS_CC_API VarInfo * makeVariableDebugInfo ( DebugInfoHelper * helper, Variable *var ); + DAS_CC_API VarInfo * makeStructVariableDebugInfo ( DebugInfoHelper * helper, const Structure * st, const Structure::FieldDeclaration * var ); + DAS_CC_API StructInfo * makeStructureDebugInfo ( DebugInfoHelper * helper, const Structure * st ); + DAS_CC_API FuncInfo * makeFunctionDebugInfo ( DebugInfoHelper * helper, const Function * fn ); + DAS_CC_API EnumInfo * makeEnumDebugInfo ( DebugInfoHelper * helper, const Enumeration * en ); + DAS_CC_API FuncInfo * makeInvokeableTypeDebugInfo ( DebugInfoHelper * helper, TypeDeclPtr blk, const LineInfo & at ); template using DebugBlockT = TBlock; - DAS_API void debug_helper_iter_structs(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); - DAS_API void debug_helper_iter_types(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); - DAS_API void debug_helper_iter_vars(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); - DAS_API void debug_helper_iter_funcs(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); - DAS_API void debug_helper_iter_enums(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); - DAS_API const char *debug_helper_find_type_cppname(DebugInfoHelper * helper, TypeInfo *info, Context * context, LineInfoArg * at); - DAS_API const char *debug_helper_find_struct_cppname(DebugInfoHelper * helper, StructInfo *info, Context * context, LineInfoArg * at); - DAS_API bool macro_aot_infix(TypeInfoMacro *macro, StringBuilderWriter *ss, ExpressionPtr expr); - DAS_API FileInfo *clone_file_info(const char *name, int tabSize, Context * context, LineInfoArg * at); - DAS_API void get_file_source_line(FileInfo * info, uint32_t line, const TBlock> & blk, Context * context, LineInfoArg * at); - DAS_API void for_each_module_function(Module *module, const TBlock &blk, Context * context, LineInfoArg * at); - DAS_API uint64_t getInitSemanticHashWithDep(ProgramPtr program, uint64_t semH); - DAS_API uint64_t getFunctionHashById(Function *fun, int id, void * pctx, Context * context, LineInfoArg * at); - DAS_API bool modAotRequire(Module *mod, StringBuilderWriter *ss, Context * context, LineInfoArg * at); + DAS_CC_API void debug_helper_iter_structs(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); + DAS_CC_API void debug_helper_iter_types(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); + DAS_CC_API void debug_helper_iter_vars(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); + DAS_CC_API void debug_helper_iter_funcs(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); + DAS_CC_API void debug_helper_iter_enums(DebugInfoHelper * helper, const DebugBlockT & block, Context * context, LineInfoArg * at); + DAS_CC_API const char *debug_helper_find_type_cppname(DebugInfoHelper * helper, TypeInfo *info, Context * context, LineInfoArg * at); + DAS_CC_API const char *debug_helper_find_struct_cppname(DebugInfoHelper * helper, StructInfo *info, Context * context, LineInfoArg * at); + DAS_CC_API bool macro_aot_infix(TypeInfoMacro *macro, StringBuilderWriter *ss, ExpressionPtr expr); + DAS_CC_API FileInfo *clone_file_info(const char *name, int tabSize, Context * context, LineInfoArg * at); + DAS_CC_API void get_file_source_line(FileInfo * info, uint32_t line, const TBlock> & blk, Context * context, LineInfoArg * at); + DAS_CC_API void for_each_module_function(Module *module, const TBlock &blk, Context * context, LineInfoArg * at); + DAS_CC_API uint64_t getInitSemanticHashWithDep(ProgramPtr program, uint64_t semH); + DAS_CC_API uint64_t getFunctionHashById(Function *fun, int id, void * pctx, Context * context, LineInfoArg * at); + DAS_CC_API bool modAotRequire(Module *mod, StringBuilderWriter *ss, Context * context, LineInfoArg * at); #include "daScript/builtin/ast_gen.inc" @@ -104,9 +104,9 @@ namespace das { } } - DAS_API void runMacroFunction ( Context * context, const string & message, const callable & subexpr ); + DAS_CC_API void runMacroFunction ( Context * context, const string & message, const callable & subexpr ); - class DAS_API VisitorAdapter : public Visitor, AstVisitor_Adapter { + class DAS_CC_API VisitorAdapter : public Visitor, AstVisitor_Adapter { public: VisitorAdapter ( char * pClass, const StructInfo * info, Context * ctx ); public: @@ -442,72 +442,72 @@ namespace das { }; DAS_API DebugAgentPtr makeDebugAgent ( const void * pClass, const StructInfo * info, Context * context ); - DAS_API Module * thisModule ( Context * context, LineInfoArg * lineinfo ); - DAS_API smart_ptr_raw thisProgram ( Context * context ); - DAS_API void astVisit ( smart_ptr_raw program, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); - DAS_API void astVisitGenerics ( smart_ptr_raw program, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); - DAS_API void astVisitModule ( smart_ptr_raw program, VisitorAdapter * adapter, + DAS_CC_API Module * thisModule ( Context * context, LineInfoArg * lineinfo ); + DAS_CC_API smart_ptr_raw thisProgram ( Context * context ); + DAS_CC_API void astVisit ( smart_ptr_raw program, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); + DAS_CC_API void astVisitGenerics ( smart_ptr_raw program, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); + DAS_CC_API void astVisitModule ( smart_ptr_raw program, VisitorAdapter * adapter, Module* module, Context * context, LineInfoArg * line_info ); - DAS_API void astVisitModulesInOrder ( smart_ptr_raw program, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); - DAS_API void astVisitFunction ( Function * func, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info); - DAS_API Expression * astVisitExpression ( Expression * expr, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info); - DAS_API TypeDecl * astVisitTypeDecl ( TypeDecl * type, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info); - DAS_API void astVisitBlockFinally ( ExprBlock * expr, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); - DAS_API PassMacroPtr makePassMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API void makeVisitor ( const void * pClass, const StructInfo * info, + DAS_CC_API void astVisitModulesInOrder ( smart_ptr_raw program, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); + DAS_CC_API void astVisitFunction ( Function * func, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info); + DAS_CC_API Expression * astVisitExpression ( Expression * expr, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info); + DAS_CC_API TypeDecl * astVisitTypeDecl ( TypeDecl * type, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info); + DAS_CC_API void astVisitBlockFinally ( ExprBlock * expr, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); + DAS_CC_API PassMacroPtr makePassMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void makeVisitor ( const void * pClass, const StructInfo * info, const TBlock & blk, Context * context, LineInfoArg * at ); - DAS_API void addModuleInferMacro ( Module * module, PassMacroPtr _newM, Context * ); - DAS_API void addModuleInferDirtyMacro ( Module * module, PassMacroPtr newM, Context * context ); - DAS_API void addModuleLintMacro ( Module * module, PassMacroPtr _newM, Context * ); - DAS_API void addModuleGlobalLintMacro ( Module * module, PassMacroPtr _newM, Context * ); - DAS_API void addModuleOptimizationMacro ( Module * module, PassMacroPtr _newM, Context * ); - DAS_API VariantMacroPtr makeVariantMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleVariantMacro ( Module * module, VariantMacroPtr newM, Context * context ); - DAS_API ForLoopMacroPtr makeForLoopMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleForLoopMacro ( Module * module, ForLoopMacroPtr _newM, Context * ); - DAS_API CaptureMacroPtr makeCaptureMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleCaptureMacro ( Module * module, CaptureMacroPtr _newM, Context * ); - DAS_API TypeMacroPtr makeTypeMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleTypeMacro ( Module * module, TypeMacroPtr _newM, Context *, LineInfoArg * ); - DAS_API SimulateMacroPtr makeSimulateMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleSimulateMacro ( Module * module, SimulateMacroPtr _newM, Context * ); - DAS_API void addModuleFunctionAnnotation ( Module * module, FunctionAnnotationPtr & ann, Context * context, LineInfoArg * at ); - DAS_API FunctionAnnotationPtr makeFunctionAnnotation ( const char * name, void * pClass, const StructInfo * info, Context * context ); - DAS_API StructureAnnotationPtr makeStructureAnnotation ( const char * name, void * pClass, const StructInfo * info, Context * context ); - DAS_API EnumerationAnnotationPtr makeEnumerationAnnotation ( const char * name, void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleStructureAnnotation ( Module * module, StructureAnnotationPtr & ann, Context * context, LineInfoArg * at ); - DAS_API void addStructureStructureAnnotation ( Structure * st, StructureAnnotationPtr & _ann, Context * context, LineInfoArg * at ); - DAS_API void addModuleEnumerationAnnotation ( Module * module, EnumerationAnnotationPtr & ann, Context * context, LineInfoArg * at ); - DAS_API int addEnumerationEntry ( Enumeration * enu, const char* name ); - DAS_API void forEachFunction ( Module * module, const char * name, const TBlock & block, Context * context, LineInfoArg * lineInfo ); - DAS_API void forEachGenericFunction ( Module * module, const char * name, const TBlock & block, Context * context, LineInfoArg * lineInfo ); - DAS_API bool addModuleFunction ( Module * module, FunctionPtr & func, Context * context, LineInfoArg * lineInfo ); - DAS_API bool addModuleGeneric ( Module * module, FunctionPtr & func, Context * context, LineInfoArg * lineInfo ); - DAS_API bool addModuleVariable ( Module * module, VariablePtr & var, Context * context, LineInfoArg * lineInfo ); - DAS_API bool addModuleKeyword ( Module * module, char * kwd, bool needOxfordComma, Context * context, LineInfoArg * lineInfo ); - DAS_API bool addModuleTypeFunction ( Module * module, char * kwd, Context * context, LineInfoArg * lineInfo ); - DAS_API VariablePtr findModuleVariable ( Module * module, const char * name ); - DAS_API bool removeModuleStructure ( Module * module, StructurePtr & _stru ); - DAS_API bool addModuleStructure ( Module * module, StructurePtr & stru ); - DAS_API bool addModuleAlias ( Module * module, TypeDeclPtr & _ptr ); - DAS_API void ast_error ( ProgramPtr prog, const LineInfo & at, const char * message, Context * context, LineInfoArg * lineInfo ); - DAS_API void ast_performance_warning ( ProgramPtr prog, const LineInfo & at, const char * message, Context * context, LineInfoArg * lineInfo ); - DAS_API void ast_style_warning ( ProgramPtr prog, const LineInfo & at, const char * message, Context * context, LineInfoArg * lineInfo ); - DAS_API void addModuleReaderMacro ( Module * module, ReaderMacroPtr newM, Context * context, LineInfoArg * lineInfo ); - DAS_API ReaderMacroPtr makeReaderMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API CommentReaderPtr makeCommentReader ( const void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleCommentReader ( Module * module, CommentReaderPtr _newM, Context * context, LineInfoArg * lineInfo ); - DAS_API void addModuleCallMacro ( Module * module, CallMacroPtr newM, Context * context, LineInfoArg * lineInfo ); - DAS_API CallMacroPtr makeCallMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API TypeInfoMacroPtr makeTypeInfoMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); - DAS_API void addModuleTypeInfoMacro ( Module * module, TypeInfoMacroPtr _newM, Context * context, LineInfoArg * at ); - DAS_API void addFunctionFunctionAnnotation(Function * func, FunctionAnnotationPtr & ann, Context* context, LineInfoArg* at); - DAS_API void addAndApplyFunctionAnnotation ( Function * func, AnnotationDeclarationPtr & ann, Context * context, LineInfoArg * at ); - DAS_API void addBlockBlockAnnotation ( ExprBlock * block, FunctionAnnotationPtr & _ann, Context * context, LineInfoArg * at ); - DAS_API void addAndApplyBlockAnnotation ( ExprBlock * blk, AnnotationDeclarationPtr & ann, Context * context, LineInfoArg * at ); - DAS_API void addAndApplyStructAnnotation ( Structure * st, AnnotationDeclarationPtr & ann, Context * context, LineInfoArg * at ); - DAS_API void visitEnumeration ( ProgramPtr program, Enumeration * enumeration, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); - DAS_API void visitStructure ( ProgramPtr program, Structure * structure, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); + DAS_CC_API void addModuleInferMacro ( Module * module, PassMacroPtr _newM, Context * ); + DAS_CC_API void addModuleInferDirtyMacro ( Module * module, PassMacroPtr newM, Context * context ); + DAS_CC_API void addModuleLintMacro ( Module * module, PassMacroPtr _newM, Context * ); + DAS_CC_API void addModuleGlobalLintMacro ( Module * module, PassMacroPtr _newM, Context * ); + DAS_CC_API void addModuleOptimizationMacro ( Module * module, PassMacroPtr _newM, Context * ); + DAS_CC_API VariantMacroPtr makeVariantMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleVariantMacro ( Module * module, VariantMacroPtr newM, Context * context ); + DAS_CC_API ForLoopMacroPtr makeForLoopMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleForLoopMacro ( Module * module, ForLoopMacroPtr _newM, Context * ); + DAS_CC_API CaptureMacroPtr makeCaptureMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleCaptureMacro ( Module * module, CaptureMacroPtr _newM, Context * ); + DAS_CC_API TypeMacroPtr makeTypeMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleTypeMacro ( Module * module, TypeMacroPtr _newM, Context *, LineInfoArg * ); + DAS_CC_API SimulateMacroPtr makeSimulateMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleSimulateMacro ( Module * module, SimulateMacroPtr _newM, Context * ); + DAS_CC_API void addModuleFunctionAnnotation ( Module * module, FunctionAnnotationPtr & ann, Context * context, LineInfoArg * at ); + DAS_CC_API FunctionAnnotationPtr makeFunctionAnnotation ( const char * name, void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API StructureAnnotationPtr makeStructureAnnotation ( const char * name, void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API EnumerationAnnotationPtr makeEnumerationAnnotation ( const char * name, void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleStructureAnnotation ( Module * module, StructureAnnotationPtr & ann, Context * context, LineInfoArg * at ); + DAS_CC_API void addStructureStructureAnnotation ( Structure * st, StructureAnnotationPtr & _ann, Context * context, LineInfoArg * at ); + DAS_CC_API void addModuleEnumerationAnnotation ( Module * module, EnumerationAnnotationPtr & ann, Context * context, LineInfoArg * at ); + DAS_CC_API int addEnumerationEntry ( Enumeration * enu, const char* name ); + DAS_CC_API void forEachFunction ( Module * module, const char * name, const TBlock & block, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API void forEachGenericFunction ( Module * module, const char * name, const TBlock & block, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API bool addModuleFunction ( Module * module, FunctionPtr & func, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API bool addModuleGeneric ( Module * module, FunctionPtr & func, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API bool addModuleVariable ( Module * module, VariablePtr & var, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API bool addModuleKeyword ( Module * module, char * kwd, bool needOxfordComma, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API bool addModuleTypeFunction ( Module * module, char * kwd, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API VariablePtr findModuleVariable ( Module * module, const char * name ); + DAS_CC_API bool removeModuleStructure ( Module * module, StructurePtr & _stru ); + DAS_CC_API bool addModuleStructure ( Module * module, StructurePtr & stru ); + DAS_CC_API bool addModuleAlias ( Module * module, TypeDeclPtr & _ptr ); + DAS_CC_API void ast_error ( ProgramPtr prog, const LineInfo & at, const char * message, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API void ast_performance_warning ( ProgramPtr prog, const LineInfo & at, const char * message, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API void ast_style_warning ( ProgramPtr prog, const LineInfo & at, const char * message, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API void addModuleReaderMacro ( Module * module, ReaderMacroPtr newM, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API ReaderMacroPtr makeReaderMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API CommentReaderPtr makeCommentReader ( const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleCommentReader ( Module * module, CommentReaderPtr _newM, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API void addModuleCallMacro ( Module * module, CallMacroPtr newM, Context * context, LineInfoArg * lineInfo ); + DAS_CC_API CallMacroPtr makeCallMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API TypeInfoMacroPtr makeTypeInfoMacro ( const char * name, const void * pClass, const StructInfo * info, Context * context ); + DAS_CC_API void addModuleTypeInfoMacro ( Module * module, TypeInfoMacroPtr _newM, Context * context, LineInfoArg * at ); + DAS_CC_API void addFunctionFunctionAnnotation(Function * func, FunctionAnnotationPtr & ann, Context* context, LineInfoArg* at); + DAS_CC_API void addAndApplyFunctionAnnotation ( Function * func, AnnotationDeclarationPtr & ann, Context * context, LineInfoArg * at ); + DAS_CC_API void addBlockBlockAnnotation ( ExprBlock * block, FunctionAnnotationPtr & _ann, Context * context, LineInfoArg * at ); + DAS_CC_API void addAndApplyBlockAnnotation ( ExprBlock * blk, AnnotationDeclarationPtr & ann, Context * context, LineInfoArg * at ); + DAS_CC_API void addAndApplyStructAnnotation ( Structure * st, AnnotationDeclarationPtr & ann, Context * context, LineInfoArg * at ); + DAS_CC_API void visitEnumeration ( ProgramPtr program, Enumeration * enumeration, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); + DAS_CC_API void visitStructure ( ProgramPtr program, Structure * structure, VisitorAdapter * adapter, Context * context, LineInfoArg * line_info ); __forceinline ExpressionPtr clone_expression ( ExpressionPtr value ) { return value ?value->clone() : nullptr; } __forceinline FunctionPtr clone_function ( FunctionPtr value ) { return value ? value->clone() : nullptr; } __forceinline TypeDeclPtr clone_type ( TypeDeclPtr value ) { return value ? new TypeDecl(*value) : nullptr; } @@ -515,84 +515,84 @@ namespace das { __forceinline void verify_expression_gc ( ExpressionPtr value ) { if ( value ) value->gc_verify(); } __forceinline StructurePtr clone_structure ( const Structure * value ) { return value ? value->clone() : nullptr; } __forceinline VariablePtr clone_variable ( VariablePtr value ) { return value ? value->clone() : nullptr; } - DAS_API void delete_expression ( ExpressionPtr expr ); - DAS_API void delete_type ( TypeDeclPtr typ ); - DAS_API void forceAtRaw ( Expression * expr, const LineInfo & at ); - DAS_API void getAstContext ( smart_ptr_raw prog, Expression * expr, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API char * get_mangled_name ( Function * func, Context * context, LineInfoArg * at ); - DAS_API char * get_mangled_name_t ( TypeDecl * typ, Context * context, LineInfoArg * at ); - DAS_API char * get_mangled_name_v ( Variable * var, Context * context, LineInfoArg * at ); - DAS_API char * get_mangled_name_b ( ExprBlock * expr, Context * context, LineInfoArg * at ); - DAS_API TypeDeclPtr parseMangledNameFn ( const char * txt, ModuleGroup & lib, Module * thisModule, Context * context, LineInfoArg * at ); - DAS_API void notInferred ( Function * func, Context * context, LineInfoArg * at ); + DAS_CC_API void delete_expression ( ExpressionPtr expr ); + DAS_CC_API void delete_type ( TypeDeclPtr typ ); + DAS_CC_API void forceAtRaw ( Expression * expr, const LineInfo & at ); + DAS_CC_API void getAstContext ( smart_ptr_raw prog, Expression * expr, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API char * get_mangled_name ( Function * func, Context * context, LineInfoArg * at ); + DAS_CC_API char * get_mangled_name_t ( TypeDecl * typ, Context * context, LineInfoArg * at ); + DAS_CC_API char * get_mangled_name_v ( Variable * var, Context * context, LineInfoArg * at ); + DAS_CC_API char * get_mangled_name_b ( ExprBlock * expr, Context * context, LineInfoArg * at ); + DAS_CC_API TypeDeclPtr parseMangledNameFn ( const char * txt, ModuleGroup & lib, Module * thisModule, Context * context, LineInfoArg * at ); + DAS_CC_API void notInferred ( Function * func, Context * context, LineInfoArg * at ); DAS_API void collectDependencies ( FunctionPtr fun, const TBlock,TArray> & block, Context * context, LineInfoArg * line ); - DAS_API bool isExprLikeCall ( ExpressionPtr expr ); - DAS_API bool isExprConst ( ExpressionPtr expr ); - DAS_API bool isTempType ( TypeDeclPtr ptr, bool refMatters ); - DAS_API float4 evalSingleExpression ( ExpressionPtr expr, bool & ok ); - DAS_API float4 evalSingleExpressionInContext ( ExpressionPtr expr, smart_ptr_raw useCtx, bool & ok ); - DAS_API ExpressionPtr makeCall ( const LineInfo & at, const char * name ); - DAS_API bool builtin_isVisibleDirectly ( Module * from, Module * too ); - DAS_API bool builtin_hasField ( TypeDeclPtr ptr, const char * field, bool constant ); - DAS_API TypeDeclPtr builtin_fieldType ( TypeDeclPtr ptr, const char * field, bool constant ); - DAS_API Module * findRttiModule ( smart_ptr THAT_PROGRAM, const char * name, Context *, LineInfoArg *); - DAS_API AnnotationPtr module_find_annotation ( const Module* module, const char *name ); - DAS_API TypeAnnotation* module_find_type_annotation ( const Module* module, const char *name ); - DAS_API Function * findRttiFunction ( Module * mod, Func func, Context * context, LineInfoArg * line_info ); - DAS_API void ast_gc_guard ( const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_module ( Program * prog, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_module_no_order ( Program * prog, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_typedef ( Module * mod, const TBlock,TypeDecl *> & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_enumeration ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_structure ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_generic ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_global ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_annotation_ordered ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_call_macro ( Module * mod, const TBlock> & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_reader_macro ( Module * mod, const TBlock> & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_variant_macro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_typeinfo_macro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_typemacro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void for_each_for_loop_macro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API Annotation * get_expression_annotation ( Expression * expr, Context * context, LineInfoArg * at ); - DAS_API Structure * find_unique_structure ( smart_ptr_raw prog, const char * name, Context * context, LineInfoArg * at ); - DAS_API Structure * module_find_structure ( const Module* module, const char * name, Context * context, LineInfoArg * at ); - DAS_API void get_use_global_variables ( Function * func, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void get_use_functions ( Function * func, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API Structure::FieldDeclaration * ast_findStructureField ( Structure * structType, const char * field, Context * context, LineInfoArg * at ); - DAS_API int32_t ast_getTupleFieldOffset ( TypeDecl * ttype, int32_t field, Context * context, LineInfoArg * at ); - DAS_API void das_comp_log ( const char * text, Context * context, LineInfoArg * at ); - DAS_API TypeInfo * das_make_type_info_structure ( Context & ctx, TypeDeclPtr ptr, Context * context, LineInfoArg * at ); - DAS_API bool isSameAstType ( TypeDeclPtr THIS, TypeDeclPtr decl, RefMatters refMatters, ConstMatters constMatters, TemporaryMatters temporaryMatters, Context * context, LineInfoArg * at ); - DAS_API void builtin_structure_for_each_field ( const BasicStructureAnnotation & ann, + DAS_CC_API bool isExprLikeCall ( ExpressionPtr expr ); + DAS_CC_API bool isExprConst ( ExpressionPtr expr ); + DAS_CC_API bool isTempType ( TypeDeclPtr ptr, bool refMatters ); + DAS_CC_API float4 evalSingleExpression ( ExpressionPtr expr, bool & ok ); + DAS_CC_API float4 evalSingleExpressionInContext ( ExpressionPtr expr, smart_ptr_raw useCtx, bool & ok ); + DAS_CC_API ExpressionPtr makeCall ( const LineInfo & at, const char * name ); + DAS_CC_API bool builtin_isVisibleDirectly ( Module * from, Module * too ); + DAS_CC_API bool builtin_hasField ( TypeDeclPtr ptr, const char * field, bool constant ); + DAS_CC_API TypeDeclPtr builtin_fieldType ( TypeDeclPtr ptr, const char * field, bool constant ); + DAS_CC_API Module * findRttiModule ( smart_ptr THAT_PROGRAM, const char * name, Context *, LineInfoArg *); + DAS_CC_API AnnotationPtr module_find_annotation ( const Module* module, const char *name ); + DAS_CC_API TypeAnnotation* module_find_type_annotation ( const Module* module, const char *name ); + DAS_CC_API Function * findRttiFunction ( Module * mod, Func func, Context * context, LineInfoArg * line_info ); + DAS_CC_API void ast_gc_guard ( const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_module ( Program * prog, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_module_no_order ( Program * prog, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_typedef ( Module * mod, const TBlock,TypeDecl *> & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_enumeration ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_structure ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_generic ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_global ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_annotation_ordered ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_call_macro ( Module * mod, const TBlock> & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_reader_macro ( Module * mod, const TBlock> & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_variant_macro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_typeinfo_macro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_typemacro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_for_loop_macro ( Module * mod, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API Annotation * get_expression_annotation ( Expression * expr, Context * context, LineInfoArg * at ); + DAS_CC_API Structure * find_unique_structure ( smart_ptr_raw prog, const char * name, Context * context, LineInfoArg * at ); + DAS_CC_API Structure * module_find_structure ( const Module* module, const char * name, Context * context, LineInfoArg * at ); + DAS_CC_API void get_use_global_variables ( Function * func, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API void get_use_functions ( Function * func, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API Structure::FieldDeclaration * ast_findStructureField ( Structure * structType, const char * field, Context * context, LineInfoArg * at ); + DAS_CC_API int32_t ast_getTupleFieldOffset ( TypeDecl * ttype, int32_t field, Context * context, LineInfoArg * at ); + DAS_CC_API void das_comp_log ( const char * text, Context * context, LineInfoArg * at ); + DAS_CC_API TypeInfo * das_make_type_info_structure ( Context & ctx, TypeDeclPtr ptr, Context * context, LineInfoArg * at ); + DAS_CC_API bool isSameAstType ( TypeDeclPtr THIS, TypeDeclPtr decl, RefMatters refMatters, ConstMatters constMatters, TemporaryMatters temporaryMatters, Context * context, LineInfoArg * at ); + DAS_CC_API void builtin_structure_for_each_field ( const BasicStructureAnnotation & ann, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API void addModuleOption ( Module * mod, char * option, Type type, Context * context, LineInfoArg * at ); - DAS_API TypeDeclPtr getUnderlyingValueType ( TypeDecl * type, Context * context, LineInfoArg * at ); - DAS_API uint32_t getHandledTypeFieldOffset ( TypeAnnotationPtr type, char * name, Context * context, LineInfoArg * at ); - DAS_API void builtin_structure_for_each_field ( const BasicStructureAnnotation & ann, + DAS_CC_API void addModuleOption ( Module * mod, char * option, Type type, Context * context, LineInfoArg * at ); + DAS_CC_API TypeDeclPtr getUnderlyingValueType ( TypeDecl * type, Context * context, LineInfoArg * at ); + DAS_CC_API uint32_t getHandledTypeFieldOffset ( TypeAnnotationPtr type, char * name, Context * context, LineInfoArg * at ); + DAS_CC_API void builtin_structure_for_each_field ( const BasicStructureAnnotation & ann, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API TypeInfo * getHandledTypeFieldType ( TypeAnnotationPtr annotation, char * name, Context * context, LineInfoArg * at ); - DAS_API TypeDeclPtr getHandledTypeFieldTypeDecl ( TypeAnnotationPtr annotation, char * name, bool isConst, Context * context, LineInfoArg * at ); - DAS_API TypeDeclPtr getHandledTypeIndexTypeDecl ( TypeAnnotation *annotation, Expression *src, Expression *idx, Context * context, LineInfoArg * at ); - DAS_API void* getVectorPtrAtIndex(void* vec, TypeDecl *type, int idx, Context * context, LineInfoArg * at); - DAS_API int32_t getVectorLength(void* vec, TypeDecl * type, Context * context, LineInfoArg * at); - DAS_API bool addModuleRequire ( Module * module, Module * reqModule, bool publ ); - DAS_API void findMatchingVariable ( Program * program, Function * func, const char * _name, bool seePrivate, + DAS_CC_API TypeInfo * getHandledTypeFieldType ( TypeAnnotationPtr annotation, char * name, Context * context, LineInfoArg * at ); + DAS_CC_API TypeDeclPtr getHandledTypeFieldTypeDecl ( TypeAnnotationPtr annotation, char * name, bool isConst, Context * context, LineInfoArg * at ); + DAS_CC_API TypeDeclPtr getHandledTypeIndexTypeDecl ( TypeAnnotation *annotation, Expression *src, Expression *idx, Context * context, LineInfoArg * at ); + DAS_CC_API void* getVectorPtrAtIndex(void* vec, TypeDecl *type, int idx, Context * context, LineInfoArg * at); + DAS_CC_API int32_t getVectorLength(void* vec, TypeDecl * type, Context * context, LineInfoArg * at); + DAS_CC_API bool addModuleRequire ( Module * module, Module * reqModule, bool publ ); + DAS_CC_API void findMatchingVariable ( Program * program, Function * func, const char * _name, bool seePrivate, const TBlock>> & block, Context * context, LineInfoArg * arg ); - DAS_API Module * getCurrentSearchModule(Program * program, Function * func, const char * _moduleName); - DAS_API bool canAccessGlobalVariable ( const VariablePtr & pVar, Module * mod, Module * thisMod ); - DAS_API TypeDeclPtr inferGenericTypeEx ( TypeDecl * type, TypeDecl * passType, bool topLevel, bool isPassType ); - DAS_API void updateAliasMapEx ( smart_ptr_raw program, TypeDecl * argType, TypeDecl * passType, Context * context, LineInfoArg * at ); - DAS_API void forceAtRaw ( Expression * expr, const LineInfo & at ); - DAS_API void forceAtFunctionRaw ( Function * func, const LineInfo & at ); - DAS_API void forceGeneratedRaw ( Expression * expr, bool setGenerated ); - DAS_API void forceGeneratedFunctionRaw ( Function * func, bool setGenerated ); - DAS_API bool add_structure_alias ( Structure * structure, char * name, const TypeDeclPtr & aliasType, Context * context, LineInfoArg * at ); - DAS_API void for_each_structure_alias ( Structure * structure, const TBlock & block, Context * context, LineInfoArg * at ); - DAS_API TypeDeclPtr get_structure_alias ( Structure * structure, const char * aliasName, Context * context, LineInfoArg * at ); - DAS_API Function * findCompilingFunctionByMangledNameHash(char * module_name, uint64_t mnh, Context * context, LineInfoArg * at); - DAS_API bool isCppKeyword ( const char * str ); - DAS_API bool isDasKeyword ( const char * str ); + DAS_CC_API Module * getCurrentSearchModule(Program * program, Function * func, const char * _moduleName); + DAS_CC_API bool canAccessGlobalVariable ( const VariablePtr & pVar, Module * mod, Module * thisMod ); + DAS_CC_API TypeDeclPtr inferGenericTypeEx ( TypeDecl * type, TypeDecl * passType, bool topLevel, bool isPassType ); + DAS_CC_API void updateAliasMapEx ( smart_ptr_raw program, TypeDecl * argType, TypeDecl * passType, Context * context, LineInfoArg * at ); + DAS_CC_API void forceAtRaw ( Expression * expr, const LineInfo & at ); + DAS_CC_API void forceAtFunctionRaw ( Function * func, const LineInfo & at ); + DAS_CC_API void forceGeneratedRaw ( Expression * expr, bool setGenerated ); + DAS_CC_API void forceGeneratedFunctionRaw ( Function * func, bool setGenerated ); + DAS_CC_API bool add_structure_alias ( Structure * structure, char * name, const TypeDeclPtr & aliasType, Context * context, LineInfoArg * at ); + DAS_CC_API void for_each_structure_alias ( Structure * structure, const TBlock & block, Context * context, LineInfoArg * at ); + DAS_CC_API TypeDeclPtr get_structure_alias ( Structure * structure, const char * aliasName, Context * context, LineInfoArg * at ); + DAS_CC_API Function * findCompilingFunctionByMangledNameHash(char * module_name, uint64_t mnh, Context * context, LineInfoArg * at); + DAS_CC_API bool isCppKeyword ( const char * str ); + DAS_CC_API bool isDasKeyword ( const char * str ); template <> struct das_iterator : das_iterator> { diff --git a/include/daScript/simulate/debug_info.h b/include/daScript/simulate/debug_info.h index 94e7f1fdc8..380d7b91c4 100644 --- a/include/daScript/simulate/debug_info.h +++ b/include/daScript/simulate/debug_info.h @@ -258,11 +258,12 @@ namespace das struct SimFunction; class Context; + class Program; class DAS_API ModuleFileAccess : public FileAccess { public: ModuleFileAccess(); - ModuleFileAccess ( const string & pak, const FileAccessPtr & access ); + ModuleFileAccess ( const string & pak, const smart_ptr & program ); virtual ~ModuleFileAccess(); bool failed() const { return !context || !modGet; } virtual ModuleInfo getModuleInfo ( const string & req, const string & from ) const override; diff --git a/include/daScript/simulate/fs_file_info.h b/include/daScript/simulate/fs_file_info.h index 7aa0a2ced3..52976378a5 100644 --- a/include/daScript/simulate/fs_file_info.h +++ b/include/daScript/simulate/fs_file_info.h @@ -29,7 +29,7 @@ namespace das { class DAS_API FsFileAccess : public das::ModuleFileAccess { public: FsFileAccess(); - FsFileAccess ( const string & pak, const FileAccessPtr & access ); + FsFileAccess ( const string & pak, const smart_ptr & program ); virtual ~FsFileAccess(); virtual void createFileSystems(); void addFileSystem ( AnyFileSystem * fs, bool firstToTry, bool sharedFs ); diff --git a/modules/dasLLVM/daslib/llvm_exe.das b/modules/dasLLVM/daslib/llvm_exe.das index a643752138..74301775b8 100644 --- a/modules/dasLLVM/daslib/llvm_exe.das +++ b/modules/dasLLVM/daslib/llvm_exe.das @@ -269,6 +269,13 @@ class CollectExternVisitor : AstVisitor { if (empty(cpp_name)) return let reg_fn_name = "jit_register_{cpp_name}" to_log(LOG_INFO, "LLVM EXE: NEED_MODULE({cpp_name}) for `{mod_name}`\n") + // ast_core / network_core live in the compiler lib, so emitting their + // jit_register thunk references compiler-only symbols — the standalone + // exe must then link the whole compiler lib. This catches dependency + // registrations (here in ensure_module) that the used_modules gate misses. + if (mod_name == "ast_core" || mod_name == "network_core") { + needs_whole_lib = true + } var reg_fn = LLVMAddFunctionWithType(g_mod, reg_fn_name, register_mod_type) LLVMBuildCall2(init_builder, register_mod_type, reg_fn, array(), "") } @@ -1049,8 +1056,14 @@ def public inject_main(program_context : Context?; ctx : LLVMContextRef; } // Determine if exe needs the whole compiler lib (rtti, ast, debugger, jit, sort-with-cblock) var needs_whole_lib = sort_needs_whole_lib + // ast_core and network_core live in the compiler lib, so registering them + // (jit_register_Module_Ast / _Network) pulls compiler-only symbols — the + // standalone exe must then link the whole compiler lib. rtti_core used to + // be listed here because it hosted the compile builtins (rtti_builtin_compile + // -> parseDaScript); those moved to the ast module, so rtti_core is now + // fully self-contained in the runtime lib and no longer needs it. for (mod_name in keys(used_modules)) { - if (mod_name == "rtti_core") { + if (mod_name == "ast_core" || mod_name == "network_core") { needs_whole_lib = true break } diff --git a/modules/dasLLVM/daslib/llvm_jit_run.das b/modules/dasLLVM/daslib/llvm_jit_run.das index 39df918657..fd589d4702 100644 --- a/modules/dasLLVM/daslib/llvm_jit_run.das +++ b/modules/dasLLVM/daslib/llvm_jit_run.das @@ -33,7 +33,7 @@ var LINK_WHOLE_LIB = false // when true, standalone exe links against the whole // invalidates cached DLLs (e.g. edits to llvm_jit.das, llvm_macro.das, llvm_jit_common.das, // runtime helper ABI, default target triple). Cache filenames fold this in, so a bump // makes every previously written DLL miss the cache on the next run and get GC'd. -let LLVM_JIT_CODEGEN_VERSION : uint64 = 0x24ul +let LLVM_JIT_CODEGEN_VERSION : uint64 = 0x25ul let JIT_FNV_PRIME : uint64 = 1099511628211ul diff --git a/src/ast/ast_module.cpp b/src/ast/ast_module.cpp index a0180c754e..aaedb422e1 100644 --- a/src/ast/ast_module.cpp +++ b/src/ast/ast_module.cpp @@ -741,7 +741,7 @@ namespace das { return it != callThis.end() ? &it->second : nullptr; } - static bool appendBuiltinModuleContent ( Module * target, ProgramPtr program, const string & modName ) { + DAS_API bool appendBuiltinModuleContent ( Module * target, ProgramPtr program, const string & modName ) { if ( !program ) { DAS_FATAL_ERROR("builtin module did not parse %s\n", modName.c_str()); return false; @@ -811,20 +811,6 @@ namespace das { return true; } - bool Module::compileBuiltinModule ( const string & modName, const unsigned char * const str, unsigned int str_len ) { - TextWriter issues; - auto access = make_smart(); - auto fileInfo = make_unique((char *) str, uint32_t(str_len), false); - access->setFileInfo(modName, das::move(fileInfo)); - ModuleGroup dummyLibGroup; - auto program = parseDaScript(modName, "", access, issues, dummyLibGroup, true); - ownFileInfo = access->letGoOfFileInfo(modName); - DAS_ASSERTF(ownFileInfo,"something went wrong and FileInfo for builtin module can not be obtained"); - auto result = appendBuiltinModuleContent(this, program, modName); - program->thisModule->module_gc_root->gc_dump_to_thread_root(); - return result; - } - bool isValidBuiltinName ( const string & name, bool canPunkt ) { if ( name.size()>=2 && name[0]=='.' && name[1]=='`') { // any name starting with .` is ok return true; diff --git a/src/ast/ast_parse.cpp b/src/ast/ast_parse.cpp index da1555cf74..8361125075 100644 --- a/src/ast/ast_parse.cpp +++ b/src/ast/ast_parse.cpp @@ -8,6 +8,8 @@ #include "daScript/misc/das_common.h" #include "daScript/simulate/aot_builtin_string.h" #include "daScript/simulate/aot_builtin_uriparser.h" +#include "daScript/simulate/fs_file_info.h" +#include "daScript/das_project_specific.h" #include "../parser/parser_state.h" @@ -26,6 +28,31 @@ int das_yyparse(yyscan_t yyscanner); void das2_yybegin(const char * str, uint32_t len, yyscan_t yyscanner); int das2_yyparse(yyscan_t yyscanner); +// get_file_access lives in the compiler lib: when given a pak it compiles the +// project-config .das (compileDaScript), so it must sit on the compiler side. +// The project-specific override stays in HAL (project_specific_file_info.cpp), +// reached here via get_project_specific_file_access(). +DAS_CC_API das::smart_ptr get_file_access( char * pak ) { + if ( auto specific = das::get_project_specific_file_access() ) + return specific(pak); +#if !DAS_NO_FILEIO + if ( pak && *pak ) { + das::ModuleGroup dummyLibGroup; + das::TextWriter tout; + auto program = das::compileDaScript(pak, das::make_smart(), tout, dummyLibGroup); + return das::make_smart(pak, program); + } else { + return das::make_smart(); + } +#else + DAS_FATAL_ERROR( + "daslang is configured with DAS_NO_FILEIO. However file access is not specified." + "set_project_specific_fs_callbacks or link-time dependency needs to be specified." + ) + return nullptr; +#endif +} + namespace das { // defined in ast_module.cpp (runtime); appends a parsed builtin module's content @@ -41,7 +68,7 @@ namespace das { module->ownFileInfo = access->letGoOfFileInfo(modName); DAS_ASSERTF(module->ownFileInfo,"something went wrong and FileInfo for builtin module can not be obtained"); auto result = appendBuiltinModuleContent(module, program, modName); - program->thisModule->module_gc_root.gc_dump_to_thread_root(); + program->thisModule->module_gc_root->gc_dump_to_thread_root(); return result; } diff --git a/src/builtin/module_builtin_ast.cpp b/src/builtin/module_builtin_ast.cpp index de45bbb222..50a9409965 100644 --- a/src/builtin/module_builtin_ast.cpp +++ b/src/builtin/module_builtin_ast.cpp @@ -10,42 +10,18 @@ #include "daScript/misc/das_common.h" #include "daScript/simulate/aot_builtin_ast.h" #include "daScript/simulate/aot_builtin_string.h" +#include "daScript/simulate/fs_file_info.h" #include "daScript/misc/performance_time.h" #include "daScript/misc/gc_node.h" MAKE_TYPE_FACTORY(StringBuilderWriter, StringBuilderWriter) #include "module_builtin_ast.h" -namespace das { - - int adapt_field_offset ( const char * fName, const StructInfo * info ) { - for ( uint32_t i=0, is=info->count; i!=is; ++i ) { - if ( strcmp(info->fields[i]->name,fName)==0 ) { - return info->fields[i]->offset; - } - } - DAS_VERIFYF(0,"mapping %s not found. not fully implemented derived class %s", fName, info->name); - return 0; - } - - int adapt_field_offset_ex ( const char * fName, const StructInfo * info, uint32_t & i ) { - for ( uint32_t is=info->count; i!=is; ++i ) { - if ( strcmp(info->fields[i]->name,fName)==0 ) { - return info->fields[i]->offset; - } - } - DAS_VERIFYF(0,"mapping %s not found. not fully implemented derived class %s", fName, info->name); - return 0; - } - char * adapt_field ( const char * fName, char * pClass, const StructInfo * info ) { - return pClass + adapt_field_offset(fName,info); - } +// get_file_access lives in the compiler lib (ast_parse.cpp); it compiles the pak. +das::FileAccessPtr get_file_access ( char * pak ); - Func adapt ( const char * funcName, char * pClass, const StructInfo * info ) { - char * field = adapt_field(funcName, pClass, info); - return field ? *(Func*)field : Func((void *)nullptr); - } +namespace das { bool addModuleFunction ( Module * module, FunctionPtr & _func, Context * context, LineInfoArg * lineInfo ) { if ( !module ) context->throw_error_at(lineInfo, "expecting module, not null"); @@ -1136,6 +1112,102 @@ namespace das { return mod->findFunctionByMangledNameHash(mnh); } + // compile-from-source builtins. The impl calls the compiler entry points + // (parseDaScript/compileDaScript) which live in the compiler lib, so these + // and their bindings live here in the ast module (compiler) rather than in + // the rtti module (runtime). + void rtti_builtin_compile ( char * modName, char * str, const CodeOfPolicies & cop, + const TBlock,const string> & block, Context * context, LineInfoArg * at ) { + return rtti_builtin_compile_ex(modName, str, cop, true, block, context, at); + } + + void rtti_builtin_compile_ex ( char * modName, char * str, const CodeOfPolicies & cop, bool exportAll, + const TBlock,const string> & block, Context * context, LineInfoArg * at ) { + str = str ? str : ((char *)""); + TextWriter issues; + uint32_t str_len = stringLengthSafe(*context, str); + auto access = make_smart(); + auto fileInfo = make_unique((char *) str, uint32_t(str_len), false); + access->setFileInfo(modName, das::move(fileInfo)); + ModuleGroup dummyLibGroup; + auto program = parseDaScript(modName, "", access, issues, dummyLibGroup, exportAll, false, cop); + if ( program ) { + if (program->failed()) { + for (auto & err : program->errors) { + issues << reportError(err.at, err.what, err.extra, err.fixme, err.cerr); + } + string istr = issues.str(); + vec4f args[3] = { + cast::from(false), + cast>::from(program), + cast::from(&istr) + }; + context->invoke(block, args, nullptr, at); + } else { + string istr = issues.str(); + vec4f args[3] = { + cast::from(true), + cast>::from(program), + cast::from(&istr) + }; + context->invoke(block, args, nullptr, at); + } + } else { + context->throw_error_at(at, "rtti_compile internal error, something went wrong"); + } + } + +#if !DAS_NO_FILEIO + void rtti_builtin_compile_file ( char * modName, smart_ptr access, ModuleGroup* module_group, const CodeOfPolicies & cop, + const TBlock,const string> & block, Context * context, LineInfoArg * at ) { + TextWriter issues; + if ( !access ) access = make_smart(); + auto program = compileDaScript(modName, access, issues, *module_group, cop); + if ( program ) { + if (program->failed()) { + for (auto & err : program->errors) { + issues << reportError(err.at, err.what, err.extra, err.fixme, err.cerr); + } + string istr = issues.str(); + vec4f args[3] = { + cast::from(false), + cast>::from(program), + cast::from(&istr) + }; + context->invoke(block, args, nullptr, at); + } else { + string istr = issues.str(); + vec4f args[3] = { + cast::from(true), + cast>::from(program), + cast::from(&istr) + }; + daScriptEnvironment::getBound()->g_Program = program; + context->invoke(block, args, nullptr, at); + daScriptEnvironment::getBound()->g_Program.reset(); + } + } else { + context->throw_error_at(at, "rtti_compile internal error, something went wrong"); + } + } +#else + void rtti_builtin_compile_file( char *, smart_ptr, ModuleGroup*, const CodeOfPolicies &, + const TBlock, const string> &, Context * context, LineInfoArg * at ) { + context->throw_error_at(at, "not supported with DAS_NO_FILEIO"); + } +#endif + +#if !DAS_NO_FILEIO + smart_ptr makeFileAccess( char * pak, Context *, LineInfoArg * ) { + return ::get_file_access(pak); + } +#else + smart_ptr makeFileAccess( char *, Context * context, LineInfoArg * at ) { + context->throw_error_at(at, "not supported with DAS_NO_FILEIO"); + return nullptr; + } +#endif + Module_Ast::Module_Ast() : Module("ast_core") { DAS_PROFILE_SECTION("Module_Ast"); ModuleLibrary lib(this); @@ -1153,6 +1225,18 @@ namespace das { } void Module_Ast::registerFunctions(ModuleLibrary & lib){ + addExtern(*this, lib, "make_file_access", + SideEffects::modifyExternal, "makeFileAccess") + ->args({"project","context","at"}); + addExtern(*this, lib, "compile", + SideEffects::modifyExternal, "rtti_builtin_compile") + ->args({"module_name","codeText","codeOfPolicies","block","context","line"}); + addExtern(*this, lib, "compile", + SideEffects::modifyExternal, "rtti_builtin_compile_ex") + ->args({"module_name","codeText","codeOfPolicies","exportAll","block","context","line"}); + addExtern(*this, lib, "compile_file", + SideEffects::modifyExternal, "rtti_builtin_compile_file") + ->args({"module_name","fileAccess","moduleGroup","codeOfPolicies","block","context","line"}); addExtern(*this, lib, "this_program", SideEffects::accessExternal, "thisProgram") ->arg("context"); diff --git a/src/builtin/module_builtin_rtti.cpp b/src/builtin/module_builtin_rtti.cpp index 79b9c379b0..1f315de37f 100644 --- a/src/builtin/module_builtin_rtti.cpp +++ b/src/builtin/module_builtin_rtti.cpp @@ -314,6 +314,37 @@ das::FileAccessPtr get_file_access( char * pak );//link time resolved dependenci das::Context * get_context ( int stackSize=0 );//link time resolved dependencies namespace das { + + + int adapt_field_offset ( const char * fName, const StructInfo * info ) { + for ( uint32_t i=0, is=info->count; i!=is; ++i ) { + if ( strcmp(info->fields[i]->name,fName)==0 ) { + return info->fields[i]->offset; + } + } + DAS_VERIFYF(0,"mapping %s not found. not fully implemented derived class %s", fName, info->name); + return 0; + } + + int adapt_field_offset_ex ( const char * fName, const StructInfo * info, uint32_t & i ) { + for ( uint32_t is=info->count; i!=is; ++i ) { + if ( strcmp(info->fields[i]->name,fName)==0 ) { + return info->fields[i]->offset; + } + } + DAS_VERIFYF(0,"mapping %s not found. not fully implemented derived class %s", fName, info->name); + return 0; + } + + char * adapt_field ( const char * fName, char * pClass, const StructInfo * info ) { + return pClass + adapt_field_offset(fName,info); + } + + Func adapt ( const char * funcName, char * pClass, const StructInfo * info ) { + char * field = adapt_field(funcName, pClass, info); + return field ? *(Func*)field : Func((void *)nullptr); + } + template <> struct das_default_vector_size { static __forceinline uint32_t size( const AnnotationArgumentList & value ) { @@ -1065,47 +1096,6 @@ namespace das { ctx->delRef(); } - void rtti_builtin_compile ( char * modName, char * str, const CodeOfPolicies & cop, - const TBlock,const string> & block, Context * context, LineInfoArg * at ) { - return rtti_builtin_compile_ex(modName, str, cop, true, block, context, at); - } - - void rtti_builtin_compile_ex ( char * modName, char * str, const CodeOfPolicies & cop, bool exportAll, - const TBlock,const string> & block, Context * context, LineInfoArg * at ) { - str = str ? str : ((char *)""); - TextWriter issues; - uint32_t str_len = stringLengthSafe(*context, str); - auto access = make_smart(); - auto fileInfo = make_unique((char *) str, uint32_t(str_len), false); - access->setFileInfo(modName, das::move(fileInfo)); - ModuleGroup dummyLibGroup; - auto program = parseDaScript(modName, "", access, issues, dummyLibGroup, exportAll, false, cop); - if ( program ) { - if (program->failed()) { - for (auto & err : program->errors) { - issues << reportError(err.at, err.what, err.extra, err.fixme, err.cerr); - } - string istr = issues.str(); - vec4f args[3] = { - cast::from(false), - cast>::from(program), - cast::from(&istr) - }; - context->invoke(block, args, nullptr, at); - } else { - string istr = issues.str(); - vec4f args[3] = { - cast::from(true), - cast>::from(program), - cast::from(&istr) - }; - context->invoke(block, args, nullptr, at); - } - } else { - context->throw_error_at(at, "rtti_compile internal error, something went wrong"); - } - } - Module * rtti_get_this_module ( smart_ptr_raw program ) { return program->thisModule.get(); } @@ -1336,43 +1326,6 @@ namespace das { #if !DAS_NO_FILEIO - void rtti_builtin_compile_file ( char * modName, smart_ptr access, ModuleGroup* module_group, const CodeOfPolicies & cop, - const TBlock,const string> & block, Context * context, LineInfoArg * at ) { - TextWriter issues; - if ( !access ) access = make_smart(); - auto program = compileDaScript(modName, access, issues, *module_group, cop); - if ( program ) { - if (program->failed()) { - for (auto & err : program->errors) { - issues << reportError(err.at, err.what, err.extra, err.fixme, err.cerr); - } - string istr = issues.str(); - vec4f args[3] = { - cast::from(false), - cast>::from(program), - cast::from(&istr) - }; - context->invoke(block, args, nullptr, at); - } else { - string istr = issues.str(); - vec4f args[3] = { - cast::from(true), - cast>::from(program), - cast::from(&istr) - }; - daScriptEnvironment::getBound()->g_Program = program; - context->invoke(block, args, nullptr, at); - daScriptEnvironment::getBound()->g_Program.reset(); - } - } else { - context->throw_error_at(at, "rtti_compile internal error, something went wrong"); - } - } - - smart_ptr makeFileAccess( char * pak, Context *, LineInfoArg * ) { - return get_file_access(pak); - } - bool introduceFile ( smart_ptr_raw access, char * fname, char * str, Context * context, LineInfoArg * at ) { if ( !fname ) context->throw_error_at(at, "expecting file name"); const char * safeStr = str ? str : ""; @@ -1382,16 +1335,6 @@ namespace das { } #else - smart_ptr makeFileAccess( char *, Context * context, LineInfoArg * at ) { - context->throw_error_at(at, "not supported with DAS_NO_FILEIO"); - return nullptr; - } - - void rtti_builtin_compile_file( char *, smart_ptr, ModuleGroup*, const CodeOfPolicies & cop, - const TBlock, const string> &, Context * context, LineInfoArg * at ) { - context->throw_error_at(at, "not supported with DAS_NO_FILEIO"); - } - bool introduceFile ( smart_ptr_raw, char *, char *, Context * context, LineInfoArg * at ) { context->throw_error_at(at, "not supported with DAS_NO_FILEIO"); return false; @@ -1775,15 +1718,6 @@ namespace das { addExtern(*this, lib, "has_module", SideEffects::modifyExternal, "rtti_has_module") ->arg("name"); - addExtern(*this, lib, "compile", - SideEffects::modifyExternal, "rtti_builtin_compile") - ->args({"module_name","codeText","codeOfPolicies","block","context","line"}); - addExtern(*this, lib, "compile", - SideEffects::modifyExternal, "rtti_builtin_compile_ex") - ->args({"module_name","codeText","codeOfPolicies","exportAll","block","context","line"}); - addExtern(*this, lib, "compile_file", - SideEffects::modifyExternal, "rtti_builtin_compile_file") - ->args({"module_name","fileAccess","moduleGroup","codeOfPolicies","block","context","line"}); addExtern(*this, lib, "for_each_expected_error", SideEffects::modifyExternal, "builtin_expected_errors") ->args({"program","block","context","line"}); @@ -1810,9 +1744,6 @@ namespace das { addExtern(*this, lib, "ast_serializer_get_data", SideEffects::modifyExternal, "rtti_ast_serializer_get_data") ->args({"serializer","block","context","line"}); - addExtern(*this, lib, "make_file_access", - SideEffects::modifyExternal, "makeFileAccess") - ->args({"project","context","at"}); addExtern(*this, lib, "set_file_source", SideEffects::modifyExternal, "introduceFile") ->args({"access","fileName","text","context","line"}); diff --git a/src/builtin/module_file_access.cpp b/src/builtin/module_file_access.cpp index 8ea61d6e13..c7eace57d7 100644 --- a/src/builtin/module_file_access.cpp +++ b/src/builtin/module_file_access.cpp @@ -17,10 +17,9 @@ namespace das { if (context) delete context; } - ModuleFileAccess::ModuleFileAccess ( const string & pak, const FileAccessPtr & access ) { - ModuleGroup dummyLibGroup; + ModuleFileAccess::ModuleFileAccess ( const string & pak, const ProgramPtr & program ) { TextWriter tout; - if ( auto program = compileDaScript(pak, access, tout, dummyLibGroup) ) { + if ( program ) { if ( program->failed() ) { for ( auto & err : program->errors ) { tout << reportError(err.at, err.what, err.extra, err.fixme, err.cerr ); diff --git a/src/builtin/module_jit.cpp b/src/builtin/module_jit.cpp index 6f71d3ade8..47f02d8e29 100644 --- a/src/builtin/module_jit.cpp +++ b/src/builtin/module_jit.cpp @@ -28,7 +28,6 @@ #include "misc/include_fmt.h" #include "module_builtin_rtti.h" -#include "module_builtin_ast.h" #include #include diff --git a/src/hal/project_specific_file_info.cpp b/src/hal/project_specific_file_info.cpp index 754f734a8c..77b61da076 100644 --- a/src/hal/project_specific_file_info.cpp +++ b/src/hal/project_specific_file_info.cpp @@ -29,26 +29,11 @@ namespace das { specificGetCloneContext = getCloneContext; } + // exposes the project-specific override to the compiler-lib get_file_access + GetFileAccessFunc get_project_specific_file_access() { return specificGetFileAccess; } + } // namespace das -DAS_API smart_ptr get_file_access( char * pak ) { - if (specificGetFileAccess) - return specificGetFileAccess(pak); -#if !DAS_NO_FILEIO - if ( pak && *pak ) { - return make_smart(pak, make_smart()); - } else { - return make_smart(); - } -#else - DAS_FATAL_ERROR( - "daslang is configured with DAS_NO_FILEIO. However file access is not specified." - "set_project_specific_fs_callbacks or link-time dependency in project_specific_file_info.cpp " - "needs to be speicied." - ) - return nullptr; -#endif -} DAS_API Context * get_context( int stackSize ) { if (specificGetNewContext) diff --git a/src/simulate/fs_file_info.cpp b/src/simulate/fs_file_info.cpp index e0d41112fc..62afae6f45 100644 --- a/src/simulate/fs_file_info.cpp +++ b/src/simulate/fs_file_info.cpp @@ -91,8 +91,8 @@ namespace das { createFileSystems(); } - FsFileAccess::FsFileAccess ( const string & pak, const FileAccessPtr & access ) - : ModuleFileAccess (pak, access) { + FsFileAccess::FsFileAccess ( const string & pak, const smart_ptr & program ) + : ModuleFileAccess (pak, program) { createFileSystems(); } diff --git a/src/simulate/simulate_fn_hash.cpp b/src/simulate/simulate_fn_hash.cpp index bf1fae1072..a49ae7914a 100644 --- a/src/simulate/simulate_fn_hash.cpp +++ b/src/simulate/simulate_fn_hash.cpp @@ -194,7 +194,7 @@ namespace das { das_hash_set variables; }; - void collectDependencies ( FunctionPtr fun, const TBlock,TArray> & block, Context * context, LineInfoArg * line ) { + DAS_API void collectDependencies ( FunctionPtr fun, const TBlock,TArray> & block, Context * context, LineInfoArg * line ) { auto program = daScriptEnvironment::getBound()->g_Program; if ( !program ) context->throw_error_at(line, "Can't collect dependencies outside of compilation."); program->markExecutableSymbolUse(); diff --git a/tests/flatten/test_flatten_errors.das b/tests/flatten/test_flatten_errors.das index ec81dc2fea..646060caca 100644 --- a/tests/flatten/test_flatten_errors.das +++ b/tests/flatten/test_flatten_errors.das @@ -2,7 +2,7 @@ options gen2 options indenting = 4 options no_aot // invokes the compiler at runtime (compile_file) — not AOT-linkable -require daslib/rtti +require daslib/ast require strings require dastest/testing_boost public diff --git a/tests/gc/gc_typedecl.das b/tests/gc/gc_typedecl.das index 9ce2ebf8c3..db375efd6f 100644 --- a/tests/gc/gc_typedecl.das +++ b/tests/gc/gc_typedecl.das @@ -6,7 +6,7 @@ options multiple_contexts options no_unused_function_arguments = false options no_unused_block_arguments = false -require daslib/rtti +require daslib/ast require daslib/debugger require dastest/testing_boost public @@ -45,7 +45,7 @@ def compile_only(file_path : string) : bool { using() $(var mg : ModuleGroup) { using() $(var cop : CodeOfPolicies) { cop.threadlock_context = true - compile_file(file_path, access, unsafe(addr(mg)), cop) $(ok, program, issues) { + compile_file(file_path, access, unsafe(addr(mg)), cop) $(ok, _program, issues) { result = ok if (!ok) { to_log(LOG_ERROR, "compile failed: {issues}\n") diff --git a/tests/jit_tests/dll_cache.das b/tests/jit_tests/dll_cache.das index 636e1b8efb..f778d34b0a 100644 --- a/tests/jit_tests/dll_cache.das +++ b/tests/jit_tests/dll_cache.das @@ -5,8 +5,8 @@ options gen2 options no_aot +require daslib/ast require daslib/fio -require daslib/rtti require strings require dastest/testing_boost @@ -44,10 +44,10 @@ def compile_probe() : string { cop.jit_enabled = true cop.jit_dll_mode = true access |> add_extra_module("just_in_time", "{get_das_root()}/daslib/just_in_time.das") - compile_file(PROBE_PATH, access, unsafe(addr(mg)), cop) $(ok, program, errors) { + compile_file(PROBE_PATH, access, unsafe(addr(mg)), cop) $(ok, program, _errors) { if (ok && program != null) { ns = string(program.thisNamespace) - simulate(program) $(sok, context, serrors) {} + simulate(program) $(_sok, _context, _serrors) {} } } } diff --git a/tests/jit_tests/jit_exe.das b/tests/jit_tests/jit_exe.das index e5b479b69d..89e0aa6016 100644 --- a/tests/jit_tests/jit_exe.das +++ b/tests/jit_tests/jit_exe.das @@ -1,8 +1,8 @@ // This file tests creating JIT executable. options gen2 options no_aot +require daslib/ast require daslib/fio -require daslib/rtti require strings require dastest/testing_boost @@ -16,7 +16,7 @@ let GLOBAL_INIT_EXE = "{OUTPUT_DIR}/jit_exe_test_global_init" def write_hello_script() : bool { var ok = false mkdir_rec(OUTPUT_DIR) - fopen(SCRIPT_PATH, "w") <| $(f) { + fopen(SCRIPT_PATH, "w") $(f) { if (f != null) { fprint(f, "options gen2\n") fprint(f, "[export] def main() \{ print(\"Hello World!\\n\"); \}\n") @@ -34,7 +34,7 @@ def write_hello_script() : bool { def write_global_init_script() : bool { var ok = false mkdir_rec(OUTPUT_DIR) - fopen(GLOBAL_INIT_SCRIPT, "w") <| $(f) { + fopen(GLOBAL_INIT_SCRIPT, "w") $(f) { if (f != null) { fprint(f, "options gen2\n") fprint(f, "let MAIN_DIR = get_das_root()\n") @@ -57,16 +57,16 @@ def compile_to_exe(t : T?; src : string; out : string) : bool { remove_result(exe_path) } var inscope access <- make_file_access("") - using <| $(var mg : ModuleGroup) { - using <| $(var cop : CodeOfPolicies) { + using() $(var mg : ModuleGroup) { + using() $(var cop : CodeOfPolicies) { cop.jit_enabled = true cop.jit_exe_mode = true cop.jit_dll_mode = false access |> add_extra_module("just_in_time", "{get_das_root()}/daslib/just_in_time.das") cop.jit_output_path := out - compile_file(src, access, unsafe(addr(mg)), cop) <| $(ok, program, errors) { + compile_file(src, access, unsafe(addr(mg)), cop) $(ok, program, _errors) { t |> equal(ok, true) - simulate(program) <| $(sok, context, serrors) { + simulate(program) $(sok, _context, _serrors) { t |> equal(sok, true) // No need to execute, we already created binary. } @@ -79,7 +79,7 @@ def compile_to_exe(t : T?; src : string; out : string) : bool { def run_exe(exe : string) : string { var output = "" unsafe { - popen("{exe}.exe") <| $(f) { + popen("{exe}.exe") $(f) { while (!feof(f)) { output += fgets(f) } @@ -111,12 +111,11 @@ def test_executable(t : T?) { // shared lib, and Windows lacks RPATH so the spawned process can't find // libDaScript.dll. Skip without daslang JIT or a shared-lib build for the // same reason — there's no library to call into at runtime. - if (get_platform_name() == "windows") { return ; } - if (!jit_enabled() || !das_is_dll_build()) { return ; } - t |> run("hello world") <| @(t : T?) { + if (get_platform_name() == "windows" || !jit_enabled() || !das_is_dll_build()) { return ; } + t |> run("hello world") @(t : T?) { test_hello_world(t) } - t |> run("global init builtin (issue #2582)") <| @(t : T?) { + t |> run("global init builtin (issue #2582)") @(t : T?) { test_global_init_builtin(t) } } diff --git a/tests/language/reflection.das b/tests/language/reflection.das index f01559d095..bf9f44b791 100644 --- a/tests/language/reflection.das +++ b/tests/language/reflection.das @@ -1,5 +1,5 @@ options gen2 -require daslib/rtti +require daslib/ast require strings require daslib/strings_boost require dastest/testing_boost public @@ -129,8 +129,8 @@ def describeVariable(glob; extra = "") { } def describeStructure(sinfo) { - var anyAnn = false - structure_for_each_annotation(sinfo) <| $(ann; annArgs) { + var _anyAnn = false + structure_for_each_annotation(sinfo) $(ann; annArgs) { let argT = join([for (arg in annArgs); "{arg.name}{describeValue(get_annotation_argument_value(arg))}"], ",") feint("[{ann.name}({argT})]\n") } @@ -152,7 +152,7 @@ def describeAnnotation(ann) { unsafe { let sann & = reinterpret(ann) feint("struct {sann.name} // {sann.fieldCount} {sann.cppName}\n") - basic_struct_for_each_field(sann) <| $(name, cppName, xtype, offset) { + basic_struct_for_each_field(sann) $(name, cppName, xtype, offset) { feint("\t{name}:{describeType(xtype)} // {cppName} at {offset}\n") } } @@ -167,22 +167,22 @@ def describeAnnotation(ann) { } def describeModule(mod) { - module_for_each_enumeration(mod) <| $(einfo) { + module_for_each_enumeration(mod) $(einfo) { describeEnumeration(einfo) } - module_for_each_structure(mod) <| $(sinfo) { + module_for_each_structure(mod) $(sinfo) { describeStructure(sinfo) } - module_for_each_annotation(mod) <| $(ann) { + module_for_each_annotation(mod) $(ann) { describeAnnotation(ann) } - module_for_each_function(mod) <| $(finfo) { + module_for_each_function(mod) $(finfo) { describeFunction(finfo) } - module_for_each_generic(mod) <| $(finfo) { + module_for_each_generic(mod) $(finfo) { describeFunction(finfo) } - module_for_each_global(mod) <| $(glob) { + module_for_each_global(mod) $(glob) { describeVariable(glob) } } @@ -194,11 +194,11 @@ def describeModule(mod) { [test] def test_compile_sample(t : T?) { var compiled_ok = false - compile("sample", sample, CodeOfPolicies()) <| $(ok; prog; errors) { + compile("sample", sample, CodeOfPolicies()) $(ok; prog; errors) { if (ok) { compiled_ok = true let thisMod = get_this_module(prog) - program_for_each_module(prog) <| $(mod) { + program_for_each_module(prog) $(mod) { if (mod == thisMod) { describeModule(mod) } @@ -220,12 +220,12 @@ def test_dollar_module(t : T?) { [test] def test_context_reflection(t : T?) { var fcount = 0 - context_for_each_function() <| $(finfo) { + context_for_each_function() $(finfo) { describeFunction(finfo) fcount++ } var vcount = 0 - context_for_each_variable() <| $(vinfo) { + context_for_each_variable() $(vinfo) { describeVariable(vinfo) vcount++ } @@ -238,20 +238,20 @@ def test_registered_modules_safe(t : T?) { // iterate registered modules — enums, structs, annotations, functions, globals // skip generics: module_for_each_generic can crash on some module RTTI var modCount = 0 - program_for_each_registered_module() <| $(mod) { - module_for_each_enumeration(mod) <| $(einfo) { + program_for_each_registered_module() $(mod) { + module_for_each_enumeration(mod) $(einfo) { describeEnumeration(einfo) } - module_for_each_structure(mod) <| $(sinfo) { + module_for_each_structure(mod) $(sinfo) { describeStructure(sinfo) } - module_for_each_annotation(mod) <| $(ann) { + module_for_each_annotation(mod) $(ann) { describeAnnotation(ann) } - module_for_each_function(mod) <| $(finfo) { + module_for_each_function(mod) $(finfo) { describeFunction(finfo) } - module_for_each_global(mod) <| $(glob) { + module_for_each_global(mod) $(glob) { describeVariable(glob) } modCount++ diff --git a/tests/module_tests/test_modules.das b/tests/module_tests/test_modules.das index cd0e18eb79..aa248cd8e2 100644 --- a/tests/module_tests/test_modules.das +++ b/tests/module_tests/test_modules.das @@ -30,7 +30,7 @@ options multiple_contexts options no_unused_function_arguments = false options no_unused_block_arguments = false -require daslib/rtti +require daslib/ast require daslib/debugger require dastest/testing_boost public diff --git a/tests/typer_errors/test_alias_message.das b/tests/typer_errors/test_alias_message.das index 6ca8c61a65..b50c5edf58 100644 --- a/tests/typer_errors/test_alias_message.das +++ b/tests/typer_errors/test_alias_message.das @@ -3,7 +3,7 @@ options gen2 options no_aot // invokes the compiler at runtime (compile_file) — not AOT-linkable -require daslib/rtti +require daslib/ast require strings require dastest/testing_boost public diff --git a/tutorials/integration/cpp/16_sandbox.cpp b/tutorials/integration/cpp/16_sandbox.cpp index 1ba0db84bc..87d0235d0f 100644 --- a/tutorials/integration/cpp/16_sandbox.cpp +++ b/tutorials/integration/cpp/16_sandbox.cpp @@ -18,6 +18,8 @@ using namespace das; +das::FileAccessPtr get_file_access( char * pak );//link time resolved dependencies + // ----------------------------------------------------------------------- // Custom file access — restrict which modules scripts can require // ----------------------------------------------------------------------- @@ -238,7 +240,7 @@ void tutorial() { // annotation_allowed() — whitelist annotations // // The host loads it via: - // FsFileAccess(projectPath, make_smart()) + // get_file_access(projectPath) // which compiles the project file, simulates it, and looks up // the exported callbacks by name. // ================================================================ @@ -247,8 +249,7 @@ void tutorial() { string projectPath = getDasRoot() + "/tutorials/integration/cpp/16_sandbox.das_project"; - auto fAccess = make_smart(projectPath, - make_smart()); + auto fAccess = get_file_access((char *) projectPath.c_str()); CodeOfPolicies policies; // The .das_project handles module/unsafe/option restrictions, @@ -267,8 +268,7 @@ void tutorial() { // Try a script that uses unsafe — blocked by module_allowed_unsafe() { - auto fAccess = make_smart(projectPath, - make_smart()); + auto fAccess = get_file_access((char *) projectPath.c_str()); fAccess->setFileInfo("unsafe_test.das", make_unique(UNSAFE_SCRIPT, uint32_t(strlen(UNSAFE_SCRIPT)), @@ -281,8 +281,7 @@ void tutorial() { // Try a script that requires a blocked module tout << "\n"; { - auto fAccess = make_smart(projectPath, - make_smart()); + auto fAccess = get_file_access((char *) projectPath.c_str()); fAccess->setFileInfo("blocked_test.das", make_unique(BLOCKED_MODULE_SCRIPT, uint32_t(strlen(BLOCKED_MODULE_SCRIPT)), diff --git a/tutorials/language/44_compile_and_run.das b/tutorials/language/44_compile_and_run.das index dedf22f72b..a530e138bf 100644 --- a/tutorials/language/44_compile_and_run.das +++ b/tutorials/language/44_compile_and_run.das @@ -25,7 +25,7 @@ options gen2 options multiple_contexts // required when holding smart_ptr -require daslib/rtti +require daslib/ast require daslib/debugger require daslib/jobque_boost diff --git a/utils/daspkg/package_runner.das b/utils/daspkg/package_runner.das index bc112981da..5332e630a0 100644 --- a/utils/daspkg/package_runner.das +++ b/utils/daspkg/package_runner.das @@ -6,6 +6,7 @@ options strict_smart_pointers = true module package_runner shared public +require daslib/ast require daslib/debugger require daslib/fio require daslib/daspkg public From fc902c21da088fe780fffb046ea601dd640f6a4c Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Thu, 4 Jun 2026 11:04:40 +0300 Subject: [PATCH 7/8] build: give compiler lib its own alloc-tracker new/delete override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RelWithDebInfo leak tracking reported thousands of cross-module orphan frees (and spurious "leaked lexer NAME tokens" / heap-leak dumps) during AOT generation after the runtime/compiler library split. DAS_TRACK_ALLOC propagates PUBLIC from libDaScript*_runtime to the compiler libs, so the compiler binary compiles tracked code — but the global operator new/delete override TU (alloc_tracker_overrides.cpp) was only compiled into the runtime libs. On Windows each DLL resolves operator new per-CRT, so libDaScriptDyn.dll's parser/infer/ast allocations escaped the tracker and read as cross-module orphan frees. Compile the override into the compiler libs too, mirroring the runtime libs (1134-1135) and the dynamic-module macro (444). Static-archive copies stay dormant (daslang_static provides the single definition), so no duplicate-symbol risk. Co-Authored-By: Claude Opus 4.8 --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a7da5d09a2..cba9e751ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1137,6 +1137,11 @@ target_compile_definitions(libDaScriptDyn_runtime PUBLIC # compiles empty in Release/Debug. target_sources(libDaScript_runtime PRIVATE src/misc/alloc_tracker_overrides.cpp) target_sources(libDaScriptDyn_runtime PRIVATE src/misc/alloc_tracker_overrides.cpp) +# The compiler lib is a separate binary (own CRT new/delete on Windows). Without +# its own copy of the override, parser/infer/ast allocations escape the tracker +# and read as cross-module orphan frees (false leaks in the RelWithDebInfo report). +target_sources(libDaScript PRIVATE src/misc/alloc_tracker_overrides.cpp) +target_sources(libDaScriptDyn PRIVATE src/misc/alloc_tracker_overrides.cpp) target_link_libraries(libDaScript libDaScript_runtime) target_link_libraries(libDaScriptDyn libDaScriptDyn_runtime) From f044fd03f506d16d91a1e4975cbc25dd7fd42cc2 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Thu, 11 Jun 2026 10:35:30 +0300 Subject: [PATCH 8/8] style_lint: STYLE029 fires only when exactly one re-export is used >=2 used = aggregation facade (daslib/ast = ast_core + rtti) Co-Authored-By: Claude Fable 5 --- daslib/style_lint.das | 23 +++++------- utils/lint/tests/_style029_mixed_proxy.das | 6 +++ .../tests/style029_transitive_require.das | 37 +++++-------------- 3 files changed, 24 insertions(+), 42 deletions(-) create mode 100644 utils/lint/tests/_style029_mixed_proxy.das diff --git a/daslib/style_lint.das b/daslib/style_lint.das index 6ccb976ff2..460e58dc5c 100644 --- a/daslib/style_lint.das +++ b/daslib/style_lint.das @@ -34,7 +34,7 @@ module style_lint shared private //! STYLE026 — nested 'unsafe { ... }' block; outer wrap already covers the scope — drop the inner //! STYLE027 — var array / table with empty default-init followed by a for-loop that only push/insert into it; use a comprehension //! STYLE028 — 'self->method(...)' inside a class method is optional — drop 'self->' and call 'method(...)' directly (compiler auto-promotes to the same invoke) -//! STYLE029 — non-public 'require X' used only for modules X re-exports (transitive-only) — require those directly and drop X (skipped when X provides macros or [init]) +//! STYLE029 — non-public 'require X' used only for ONE module X re-exports — require it directly and drop X (skipped when ≥2 re-exports are used: aggregation facade; or when X provides macros or [init]) //! STYLE030 — non-public 'require X' that is entirely unused — no symbol from X (or anything it re-exports) is referenced; drop it (skipped when X provides any macro or an [init], or only re-exports builtins used through it, or X or its public re-export closure exports a function matching an unresolved call inside an uninstanced generic body). Suppress a deliberate keep with '// nolint:STYLE030' require daslib/ast_boost @@ -1683,26 +1683,21 @@ class StyleLintVisitor : AstVisitor { var closure : table st029_collect_public_deps(mod, closure) var via : array - var used_any = false + var used_count = 0 for (cm in keys(closure)) { if (!key_exists(used_modules, cm)) continue - used_any = true + used_count++ if (closure?[cm] ?? false) via |> push(cm) } var line_at = at - if (!empty(via)) { - sort(via) - let mods = build_string() $(w) { - for (i in range(length(via))) { - if (i > 0) { w |> write(", ") } - w |> write(via[i]) - } - } - style_warning("STYLE029: require {req_name} is used only for modules it re-exports ({mods}); require those directly and drop {req_name}", line_at) + // >=2 used re-exports = aggregation facade; single used builtin has + // no requirable replacement — both stay silent. + if (used_count == 1 && !empty(via)) { + let mods = via[0] + style_warning("STYLE029: require {req_name} is used only for the module it re-exports ({mods}); require it directly and drop {req_name}", line_at) return } - // Skip when only builtin-facade re-exports are used (legitimate). - return if (used_any) + return if (used_count > 0) // Nothing direct, nothing transitive, no macro/[init] — genuinely unused. style_warning("STYLE030: require {req_name} is unused — no symbol from it (or a module it re-exports) is referenced; drop it", line_at) } diff --git a/utils/lint/tests/_style029_mixed_proxy.das b/utils/lint/tests/_style029_mixed_proxy.das new file mode 100644 index 0000000000..4c744dd233 --- /dev/null +++ b/utils/lint/tests/_style029_mixed_proxy.das @@ -0,0 +1,6 @@ +options gen2 + +module _style029_mixed_proxy + +require math public +require _style029_leaf public diff --git a/utils/lint/tests/style029_transitive_require.das b/utils/lint/tests/style029_transitive_require.das index d321825c3a..5e3ef46399 100644 --- a/utils/lint/tests/style029_transitive_require.das +++ b/utils/lint/tests/style029_transitive_require.das @@ -1,36 +1,17 @@ options gen2 -// STYLE029: non-public 'require X' used only for modules X re-exports -// (transitive-only) — require those directly and drop X. -// -// Problem: requiring a module purely as a conduit to symbols it re-exports -// publicly hides the real dependency. The proxy can change its re-exports out -// from under you, and a reader can't tell what you actually depend on. -// -// Bad pattern: -// require proxy // proxy does `require leaf public` -// ... leaf_value() ... // only leaf's symbols are used -// -// Good pattern: -// require leaf -// ... leaf_value() ... -// -// Guards that suppress the warning (no false positives): -// * the required module is used directly (>=1 of its own symbols referenced) -// * the module registers a compile-time macro (pessimistic — its uses leave -// no traceable AST node) -// * the module has an [init] function (runs side effects on load) -// * nothing it re-exports is used either (genuinely unused — deferred, a -// separate concern from transitive-only) +// STYLE029: 'require X' used only for ONE module X re-exports — require it +// directly and drop X. Silent when >=2 re-exports are used (aggregation +// facade, e.g. daslib/ast) or the single used re-export is builtin. expect 31209:1 require daslib/style_lint -require _style029_proxy // transitive-only — only the leaf's symbol is used (FIRES) -require _style029_direct // used directly — must NOT fire +require _style029_proxy // only leaf used — FIRES +require _style029_direct // used directly — silent +require _style029_mixed_proxy // math + leaf both used — silent [export] -def use_them() : int { - // style029_leaf_value is re-exported by the proxy; style029_direct_value is - // the direct module's own symbol. - return style029_leaf_value() + style029_direct_value() +def use_them(v : float) : int { + // sqrt(v) keeps the math use alive through const-folding + return style029_leaf_value() + style029_direct_value() + int(sqrt(v)) }