ELENA-LANG / elena-lang

ELENA is a general-purpose language with late binding. It is multi-paradigm, combining features of functional and object-oriented programming. Rich set of tools are provided to deal with message dispatching : multi-methods, message qualifying, generic message handlers, run-time interfaces
https://elena-lang.github.io/
MIT License
236 stars 26 forks source link

Install to different location #696

Closed mingodad closed 1 month ago

mingodad commented 1 month ago

I'm on a Ubuntu 18.04 64bits and want to install elena to a local folder $HOME/local/elena but it seems that the installation folder is hardcoded to be: https://github.com/ELENA-LANG/elena-lang/blob/8938a86917d0aeabd55d417bb68f967e2b578a4e/elenasrc3/elc/linux/constants.h#L12-L18

Also it's hard coded in other places too, maybe it could be wrapped with preprocessor macro to allow override like:

namespace elena_lang
{
   // compiler service files
#ifdef USER_CUSTOM_DEFAULT_CONFIG
   constexpr auto DEFAULT_CONFIG = USER_CUSTOM_DEFAULT_CONFIG;
#else
   constexpr auto DEFAULT_CONFIG = "/etc/elena/elc60.config";
#endif
#ifdef USER_CUSTOM_DATA_PATH
   constexpr auto DATA_PATH = USER_CUSTOM_DATA_PATH;
#else
   constexpr auto DATA_PATH = "/usr/share/elena";
#endif

}

Is already another way to achieve it ?

arakov commented 1 month ago

Hi. Sure, I can add this macro.

I know, an alternative can be a symbolic link. Maybe you have by chance any best practices for paths in Linux? For example all paths to the shared libraries are hard-coded as well.

I didn't pay much attention to it so far, as I've got no complains about them.

mingodad commented 1 month ago

Thank you for reply ! I'm trying right now to build/install hardcoding my desired paths and will test it then if I succed I'll try to figure out how to make it configurable and will post here what I achieve.

mingodad commented 1 month ago

No luck so far and I can't even test it form the build dir. Would be nice if could have a build where the executables expect all they need to be relative to it's path.

mingodad commented 1 month ago

Or an option to pass to then the path for the config/templates/lib/...

mingodad commented 1 month ago

Also when building on linux there is no elt-cli only asm64-cli, ecv64-cli, elena64-cli, og64-cli and sg64-cli, no ide and I can't find the info on how to build it yet.

mingodad commented 1 month ago

I could get the https://github.com/ELENA-LANG/elena-lang/releases/download/v6.3.0/elena-lang-6.3.0.x64-win.zip unziped to a folder and execute the ide with wine (the ide font size is too small, the editor font is configurable and I could get a font size of my choice). I could compile the examples/console/helloworld but when try to execute I get:

wine elena64-ide.exe 
0025:err:winedevice:async_create_driver failed to create driver L"NPF": c0000001
001e:err:winedevice:async_create_driver failed to create driver L"nsiproxy": c0000142
0046:err:module:import_dll Library elenart60_64.dll (which is needed by L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe") not found
0046:err:module:attach_dlls Importing dlls for L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe" failed, status c0000135

If I create a symbolic link to elenart60_64.dll in the same folder of helloworld.exe then it works.

arakov commented 1 month ago

The simplest way to install all required shared files is to use the script:

for x86-64 : build/amd64/build_package_amd64.script for x86 : build/i386/build_package_i386.script for AARCH64 : build/aarch64/build_package_arm64.script for PPC64le : build/ppc64le/build_package_ppc64le.script

you have to execute them with SUDO

As for the relative paths - sure, I will do it. For Windows it is implemented like this. For Linux there is no simple solution to get a path where the executable is located. So I will add an option to provide the path where data / config files are located. But what about path to shared library?

The work on porting IDE to Linux is not yet finished. Let me know if you are interested, so I can prioritize it

What platform do you use?

mingodad commented 1 month ago

Even the windows zip doesn't include the elt-cli.exe mentioned on https://github.com/ELENA-LANG/elena-lang/wiki/ELENA-Programming-Manual#language-environment

arakov commented 1 month ago

I could get the https://github.com/ELENA-LANG/elena-lang/releases/download/v6.3.0/elena-lang-6.3.0.x64-win.zip unziped to a folder and execute the ide with wine (the ide font size is too small, the editor font is configurable and I could get a font size of my choice). I could compile the examples/console/helloworld but when try to execute I get:

wine elena64-ide.exe 
0025:err:winedevice:async_create_driver failed to create driver L"NPF": c0000001
001e:err:winedevice:async_create_driver failed to create driver L"nsiproxy": c0000142
0046:err:module:import_dll Library elenart60_64.dll (which is needed by L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe") not found
0046:err:module:attach_dlls Importing dlls for L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe" failed, status c0000135

If I create a symbolic link to elenart60_64.dll in the same folder of helloworld.exe then it works.

Yes, for windows, the shared library elenart60_64.dll / elenart60.dll must be located in the folder which included in PATHS or the current one. Alternatively you can copy them to WINDOWS/System32 or WINDOWS/SysWOW64 (for 64 bit version)

arakov commented 1 month ago

Even the windows zip doesn't include the elt-cli.exe mentioned on https://github.com/ELENA-LANG/elena-lang/wiki/ELENA-Programming-Manual#language-environment

It is in the another zip file - https://github.com/ELENA-LANG/elena-lang/releases/download/v6.3.0/elena-lang-6.3.0.x86-win.zip For simplicity, I didn't include into 64 bit version, 32 bit files.

mingodad commented 1 month ago

While trying to build again and running under valgrind I'm getting this warnings:

Parsing operations/inline.l
==3521== Conditional jump or move depends on uninitialised value(s)
==3521==    at 0x1E9E38: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:50)
==3521==    by 0x1EC991: elena_lang::SyntaxTreeBuilder::flushAttribute(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, unsigned int&, bool, int) [clone .constprop.1] (derivation.cpp:815)
==3521==    by 0x1EF721: elena_lang::SyntaxTreeBuilder::flushDescriptor(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool, bool, bool) (derivation.cpp:771)
==3521==    by 0x1F68F3: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1711)
==3521==    by 0x1F7658: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==3521==    by 0x1F78C2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==3521==    by 0x1F7A6D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==3521==    by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==3521==    by 0x1E4E2E: elena_lang::CompilingProcess::buildModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTree*, elena_lang::ForwardResolverBase*, elena_lang::CompilingProcess::ModuleSettings&, int, int) (compiling.cpp:576)
==3521==    by 0x1E678B: elena_lang::CompilingProcess::compile(elena_lang::ProjectBase&, unsigned int, unsigned int, unsigned int, int) (compiling.cpp:680)
==3521==    by 0x1E7739: elena_lang::CompilingProcess::build(elena_lang::Project&, elena_lang::LinkerBase&, unsigned int, unsigned int, unsigned int, int, elena_lang::ustr_t) (compiling.cpp:813)
==3521==    by 0x11FBE8: main (elc.cpp:306)
==3521== 
==3521== Conditional jump or move depends on uninitialised value(s)
==3521==    at 0x1E9E38: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:50)
==3521==    by 0x1EF9EE: elena_lang::SyntaxTreeBuilder::flushDescriptor(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool, bool, bool) (derivation.cpp:799)
==3521==    by 0x1F68F3: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1711)
==3521==    by 0x1F7658: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==3521==    by 0x1F78C2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==3521==    by 0x1F7A6D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==3521==    by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==3521==    by 0x1E4E2E: elena_lang::CompilingProcess::buildModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTree*, elena_lang::ForwardResolverBase*, elena_lang::CompilingProcess::ModuleSettings&, int, int) (compiling.cpp:576)
==3521==    by 0x1E678B: elena_lang::CompilingProcess::compile(elena_lang::ProjectBase&, unsigned int, unsigned int, unsigned int, int) (compiling.cpp:680)
==3521==    by 0x1E7739: elena_lang::CompilingProcess::build(elena_lang::Project&, elena_lang::LinkerBase&, unsigned int, unsigned int, unsigned int, int, elena_lang::ustr_t) (compiling.cpp:813)
==3521==    by 0x11FBE8: main (elc.cpp:306)
==3521== 
Parsing operations/operations.l
==3521== Conditional jump or move depends on uninitialised value(s)
==3521==    at 0x1E9E38: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:50)
==3521==    by 0x1E9D03: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==3521==    by 0x1E9E65: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==3521==    by 0x1F6A95: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1725)
==3521==    by 0x1F7658: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==3521==    by 0x1F78C2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==3521==    by 0x1F7A6D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==3521==    by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==3521==    by 0x1E4E2E: elena_lang::CompilingProcess::buildModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTree*, elena_lang::ForwardResolverBase*, elena_lang::CompilingProcess::ModuleSettings&, int, int) (compiling.cpp:576)
==3521==    by 0x1E678B: elena_lang::CompilingProcess::compile(elena_lang::ProjectBase&, unsigned int, unsigned int, unsigned int, int) (compiling.cpp:680)
==3521==    by 0x1E7739: elena_lang::CompilingProcess::build(elena_lang::Project&, elena_lang::LinkerBase&, unsigned int, unsigned int, unsigned int, int, elena_lang::ustr_t) (compiling.cpp:813)
==3521==    by 0x11FBE8: main (elc.cpp:306)
==3521== 
Compiling system'operations
saving system'operations
mingodad commented 1 month ago

And moving this code :

   if (!testNodeMask(node.key, SyntaxKey::TerminalMask) || !scope.ignoreTerminalInfo) {
      flushCollection(writer, scope, node);
   }

To:

   if (!testNodeMask(node.key, SyntaxKey::TerminalMask)
       || !scope.ignoreTerminalInfo) { ///<<<!!!! Line 51
      flushCollection(writer, scope, node);
   }

Then the warning line changes from 50 to 51 that mean scope.ignoreTerminalInfo is being checked without been initialized.

mingodad commented 1 month ago

Maybe the uninitialized value is scope !

mingodad commented 1 month ago

After adding initialization here:

-------------------------- elenasrc3/elc/derivation.h --------------------------
index 5143257ab..38ccaf80c 100644
@@ -233,13 +233,14 @@ namespace elena_lang
          _cacheWriter.newNode(SyntaxKey::Root);
       }

-      SyntaxTreeBuilder(SyntaxTree* target, ErrorProcessor* errorProcessor, 
+      SyntaxTreeBuilder(SyntaxTree* target, ErrorProcessor* errorProcessor,
          ModuleScopeBase* moduleScope, TemplateProssesorBase* templateProcessor)
          : _writer(*target), _cacheWriter(_cache)
       {
          _errorProcessor = errorProcessor;
          _moduleScope = moduleScope;
          _templateProcessor = templateProcessor;
+         _noDebugInfo = false;  ///<<<<!!!!! here adding initialization

          _writer.clear();
          _writer.newNode(SyntaxKey::Root);

Now it run a lot longer without warnings then there is this one:

Parsing operations/inline.l
Parsing operations/operations.l
Compiling system'operations
saving system'operations
Parsing operations/advanced/operations.l
Compiling system'operations'advanced
saving system'operations'advanced
Parsing inline_templates.l
Parsing object.l
Parsing basic.l
Parsing variables.l
Parsing primitives.l
Parsing enumerables.l
==4542== Invalid read of size 2
==4542==    at 0x4C3D3A0: memmove (vg_replace_strmem.c:1400)
==4542==    by 0x121673: memcpy (string_fortified.h:34)
==4542==    by 0x121673: write (dump.cpp:82)
==4542==    by 0x121673: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:77)
==4542==    by 0x1E9DC6: write (streams.h:509)
==4542==    by 0x1E9DC6: writeString (streams.h:362)
==4542==    by 0x1E9DC6: saveStrArgument (tree.h:130)
==4542==    by 0x1E9DC6: newNode (tree.h:596)
==4542==    by 0x1E9DC6: copyNewNode (syntaxtree.h:276)
==4542==    by 0x1E9DC6: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==4542==    by 0x1E9D13: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==4542==    by 0x1E9E75: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==4542==    by 0x1EA47A: elena_lang::SyntaxTreeBuilder::copyHeader(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1231)
==4542==    by 0x1F4D11: elena_lang::SyntaxTreeBuilder::flushSubScopeMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1250)
==4542==    by 0x1F4F51: elena_lang::SyntaxTreeBuilder::flushSubScope(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1277)
==4542==    by 0x1F57C4: elena_lang::SyntaxTreeBuilder::flushClassMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1350)
==4542==    by 0x1F59D8: elena_lang::SyntaxTreeBuilder::flushClass(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1396)
==4542==    by 0x1F73B1: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1774)
==4542==    by 0x1F7668: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==4542==  Address 0x57aa27e is 60,174 bytes inside a block of size 60,224 free'd
==4542==    at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==4542==    by 0x1216B0: reserve (dump.cpp:52)
==4542==    by 0x1216B0: reserve (dump.cpp:48)
==4542==    by 0x1216B0: resize (dump.cpp:65)
==4542==    by 0x1216B0: resize (dump.cpp:60)
==4542==    by 0x1216B0: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:80)
==4542==    by 0x1E9DC6: write (streams.h:509)
==4542==    by 0x1E9DC6: writeString (streams.h:362)
==4542==    by 0x1E9DC6: saveStrArgument (tree.h:130)
==4542==    by 0x1E9DC6: newNode (tree.h:596)
==4542==    by 0x1E9DC6: copyNewNode (syntaxtree.h:276)
==4542==    by 0x1E9DC6: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==4542==    by 0x1E9D13: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==4542==    by 0x1E9E75: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==4542==    by 0x1EA47A: elena_lang::SyntaxTreeBuilder::copyHeader(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1231)
==4542==    by 0x1F4D11: elena_lang::SyntaxTreeBuilder::flushSubScopeMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1250)
==4542==    by 0x1F4F51: elena_lang::SyntaxTreeBuilder::flushSubScope(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1277)
==4542==    by 0x1F57C4: elena_lang::SyntaxTreeBuilder::flushClassMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1350)
==4542==    by 0x1F59D8: elena_lang::SyntaxTreeBuilder::flushClass(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1396)
==4542==    by 0x1F73B1: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1774)
==4542==    by 0x1F7668: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==4542==  Block was alloc'd at
==4542==    at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==4542==    by 0x1216B0: reserve (dump.cpp:52)
==4542==    by 0x1216B0: reserve (dump.cpp:48)
==4542==    by 0x1216B0: resize (dump.cpp:65)
==4542==    by 0x1216B0: resize (dump.cpp:60)
==4542==    by 0x1216B0: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:80)
==4542==    by 0x1E9DC6: write (streams.h:509)
==4542==    by 0x1E9DC6: writeString (streams.h:362)
==4542==    by 0x1E9DC6: saveStrArgument (tree.h:130)
==4542==    by 0x1E9DC6: newNode (tree.h:596)
==4542==    by 0x1E9DC6: copyNewNode (syntaxtree.h:276)
==4542==    by 0x1E9DC6: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==4542==    by 0x1EC9A1: elena_lang::SyntaxTreeBuilder::flushAttribute(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, unsigned int&, bool, int) [clone .constprop.1] (derivation.cpp:815)
==4542==    by 0x1EF731: elena_lang::SyntaxTreeBuilder::flushDescriptor(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool, bool, bool) (derivation.cpp:771)
==4542==    by 0x1F4FE7: elena_lang::SyntaxTreeBuilder::flushClassMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1315)
==4542==    by 0x1F59D8: elena_lang::SyntaxTreeBuilder::flushClass(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1396)
==4542==    by 0x1F73B1: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1774)
==4542==    by 0x1F7668: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==4542==    by 0x1F78D2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==4542==    by 0x1F7A7D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==4542==    by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==4542== 
...
mingodad commented 1 month ago

The key for this problem is in this part of the valgrind message:

==4542==  Address 0x57aa27e is 60,174 bytes inside a block of size 60,224 free'd
==4542==    at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==4542==    by 0x1216B0: reserve (dump.cpp:52)
==4542==    by 0x1216B0: reserve (dump.cpp:48)
==4542==    by 0x1216B0: resize (dump.cpp:65)
==4542==    by 0x1216B0: resize (dump.cpp:60)
mingodad commented 1 month ago

Looking at this code:

void MemoryDump :: reserve(pos_t size)
{
   if (size > _total) {
      const pos_t newSize = align(size, SECTION_PAGE_SIZE);     
      void* newBuffer = realloc(_buffer, newSize);
      if (newBuffer) {
         _buffer = newBuffer;
         _total = newSize;
      }
   }
}

If the call to realloc fail this function silently hide the error and let the program continue. Shouldn't an error somehow be returned or halt the program ?

arakov commented 1 month ago

Maybe the uninitialized value is scope !

  • _noDebugInfo = false; ///<<<<!!!!! here adding initialization Yes, good catch. I've missed that one. And it is passed further to Scope
void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode node)
{
   Scope scope(_noDebugInfo);

If the call to realloc fail this function silently hide the error and let the program continue. Shouldn't an error somehow be returned or halt the program ?

In normal circumstances it is highly unlikely, but of course better safe than sorry. I will fix it as well.

Thanks a lot.

mingodad commented 1 month ago

In this code in tree.h :

      pos_t saveStrArgument(ustr_t strArgument)
      {
         MemoryWriter stringWriter(&_strings);

         pos_t position = stringWriter.position();

         stringWriter.writeString(strArgument, getlength_pos(strArgument) + 1);

         return position;
      }

using this from tools.h :

inline pos_t getlength_pos(const char* s)
{
   return (s == nullptr) ? 0 : (pos_t)strlen(s);
}

What happens when strArgument is NULL ? Are you trying to write 1 byte from a NULL ?

arakov commented 1 month ago

What happens when strArgument is NULL ? Are you trying to write 1 byte from a NULL ?

It will crash :) . In defense, it never did though ;) I've fixed it, Thanks a lot.

mingodad commented 1 month ago

I've noticed that in derivation.h you are passing SyntaxNode node as value in a lot of places couldn't SyntaxNode &node be a better choice ?

mingodad commented 1 month ago

In this code from dump.cpp:

bool MemoryDump :: write(pos_t position, const void* s, pos_t length)
{
   if (position <= _used) {
      resize(position + length);

      memcpy(static_cast<char*>(_buffer) + position, s, length);

      return true;
   }
   else return false;

}

bool MemoryDump :: insert(pos_t position, const void* s, pos_t length)
{
   if (position <= _used) {
      resize(_used + length);

      memmove(get(position + length), get(position), _used - position - length);
      if (s != nullptr)
         memcpy(get(position), s, length);

      return true;
   }
   else return false;
}

This test if (position <= _used) { should not be if (position >= _used) { ?

mingodad commented 1 month ago

Sorry ! Forget my previous message.

arakov commented 1 month ago

This test if (position <= _used) { should not be if (position >= _used) { ?

No, it is correct. I'm inserting inside the allocated buffer.

arakov commented 1 month ago

Sorry ! Forget my previous message.

Sure, no problem, Anyway thanks for your comments. It is always nice to have a fresh look. :)

arakov commented 1 month ago

I've noticed that in derivation.h you are passing SyntaxNode node as value in a lot of places couldn't SyntaxNode &node be a better choice ?

Yes, I will review them. Sometimes it can be dangerous if the node is reassigned. I will look and modify when it is possible

mingodad commented 1 month ago

In this piece of code in compiler.cpp:

      // if it is an explicit constant conversion
      if (constantConversion) {
         NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);

         addExtensionMessage(scope, scope.message, scope.getClassRef(), scope.message,
            scope.getClassVisibility() != Visibility::Public);
      }

g++ 9.4 emit this warning:

../elenasrc3/elc/compiler.cpp: In member function ‘void elena_lang::Compiler::declareVMTMessage(elena_lang::Compiler::MethodScope&, elena_lang::SyntaxNode, bool, bool, bool)’:
../elenasrc3/elc/compiler.cpp:3995:26: warning: unused variable ‘nsScope’ [-Wunused-variable]
 3995 |          NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);
      |                          ^~~~~~~

Maybe do you intended to use nsScope instead of scope here ?

         addExtensionMessage(scope, scope.message, scope.getClassRef(), scope.message,
            scope.getClassVisibility() != Visibility::Public);
mingodad commented 1 month ago

Same thing as the previous message here:

   else {
      // HOTFIX : generate a temporal template to pass the type
      SyntaxTree dummyTree;
      List<SyntaxNode> parameters({});
      declareTemplateParameters(scope.module, typeList, dummyTree, parameters);

      ref_t templateRef = mapTemplateType(scope, terminalNode, parameters.count());
      if (!templateRef)
         scope.raiseError(errUnknownClass, terminalNode);

      NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);

      return _templateProcessor->generateClassTemplate(*scope.moduleScope,
         templateRef, parameters, declarationMode, nullptr);
   }
mingodad commented 1 month ago

Again here:

   smName.append("#1");

   ref_t templateReference = 0;
   if (isWeakReference(*smName)) {
      templateReference = scope.module->mapReference(*smName, true);
   }
   else templateReference = scope.moduleScope->mapFullReference(*smName, true);

   NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);

   return _templateProcessor->generateClassTemplate(*scope.moduleScope,
      templateReference, parameters, false, nullptr);
}

And here:

   ref_t templateReference = 0;
   if (isWeakReference(*tupleName)) {
      templateReference = scope.module->mapReference(*tupleName, true);
   }
   else templateReference = scope.moduleScope->mapFullReference(*tupleName, true);

   if (!templateReference)
      scope.raiseError(errInvalidOperation, node);

   NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);

   return _templateProcessor->generateClassTemplate(*scope.moduleScope,
      templateReference, parameters, false, nullptr);
}

...

mingodad commented 1 month ago

And here in compiler.h :

         Scope(Scope* parent)
         {
            this->parent = parent;
            if (parent) {
               this->module = parent->module;
               this->moduleScope = parent->moduleScope;
               this->compilerLogic = compilerLogic;
            }
            else {
               this->module = nullptr;
               this->moduleScope = nullptr;
               this->compilerLogic = nullptr;
            }
         }
In file included from ../elenasrc3/elc/compiler.cpp:9:
../elenasrc3/elc/compiler.h: In constructor ‘elena_lang::Compiler::Scope::Scope(elena_lang::Compiler::Scope*)’:
../elenasrc3/elc/compiler.h:459:38: warning: ‘*<unknown>.elena_lang::Compiler::Scope::compilerLogic’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  459 |                this->compilerLogic = compilerLogic;
      |                                      ^~~~~~~~~~~~~

Probably do you intended this ?

this->compilerLogic = parent->compilerLogic;
mingodad commented 1 month ago

And in elfarmimage.cpp:

      // relocation table entry
      pos_t relPosition = reltabWriter.position() - reltabOffset;
      reltabWriter.writeQReference(importRef, gotPosition);
      reltabWriter.writeQWord((symbolIndex << 32) + relocateType);
      reltabWriter.writeQWord(0);
../elenasrc3/elc/linux/elfarmimage.cpp: In member function ‘virtual void elena_lang::ElfARM64ImageFormatter::fillElfData(elena_lang::ImageProviderBase&, elena_lang::ElfImageFormatter::ElfData&, elena_lang::pos_t, elena_lang::RelocationMap&)’:
../elenasrc3/elc/linux/elfarmimage.cpp:93:13: warning: unused variable ‘relPosition’ [-Wunused-variable]
   93 |       pos_t relPosition = reltabWriter.position() - reltabOffset;
      |             ^~~~~~~~~~~

Did you intended to use relPosition ?

arakov commented 1 month ago

g++ 9.4 emit this warning: Maybe do you intended to use nsScope instead of scope here ?

No, in most cases they are left-overs. My VS doesn't like to warn me about unused variables. :) I see them only then I compile under Linux. I've fixed bunch of them now.

Probably do you intended this ?

this->compilerLogic = parent->compilerLogi

Thanks, good catch. I've fixed it.

Did you intended to use relPosition ?

No, I've commented it now. Probably left after debugging / porting from Intel CPU code.

arakov commented 1 month ago

As for the main topic of this issue. I've fixed the compiler code, it will now try to look for data and config files in the executable folder and use them. But paths in elc60.config file must be modified. I will think over the best and most optimal way to do it. Probably I can have two sets of config files - local with relative paths and default ones

mingodad commented 1 month ago

I think that I finally found the problem reported by valgrind:

Parsing enumerables.l
==15531== Invalid read of size 2
==15531==    at 0x4C3D3A0: memmove (vg_replace_strmem.c:1400)
==15531==    by 0x1386FF: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:82)
==15531==    by 0x14BA88: elena_lang::MemoryWriter::write(void const*, unsigned int) (streams.h:509)
==15531==    by 0x161185: elena_lang::StreamWriter::writeString(elena_lang::ustr_t, unsigned int) (streams.h:362)
==15531==    by 0x17D789: elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::saveStrArgument(elena_lang::ustr_t) (tree.h:130)
==15531==    by 0x17D2BA: elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer::newNode(elena_lang::SyntaxKey, elena_lang::ustr_t) (tree.h:596)
==15531==    by 0x1F7562: elena_lang::SyntaxTree::copyNewNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (syntaxtree.h:276)
==15531==    by 0x1EDA6F: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==15531==    by 0x1EDB4A: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==15531==    by 0x1EDACB: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==15531==    by 0x1F3485: elena_lang::SyntaxTreeBuilder::copyHeader(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1231)
==15531==    by 0x1F35ED: elena_lang::SyntaxTreeBuilder::flushSubScopeMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1250)
==15531==  Address 0x57aa27e is 60,174 bytes inside a block of size 60,224 free'd
==15531==    at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==15531==    by 0x13861A: elena_lang::MemoryDump::reserve(unsigned int) (dump.cpp:52)

Following the call chain I arrived at syntaxtree.h:

      static void copyNewNode(SyntaxTreeWriter& writer, SyntaxNode node)
      {
         if (node.arg.strArgPosition != INVALID_POS) {
            writer.newNode(node.key, node.identifier()); ////<<<<!!!!! Here
         }
         else writer.newNode(node.key, node.arg.reference);
      }

The problem seem that node.identifier():

         ustr_t identifier()
         {
            if (arg.strArgPosition != INVALID_POS) {
               return (const char*)(_tree->_strings.get(arg.strArgPosition)); ///!!!!<<< HERE
            }
            else return nullptr;
         }

returns a pointer inside _buffer :

void* MemoryDump :: get(pos_t position) const
{
   if (position < _used) {
      return (char*)_buffer + position; ////<<<<!!! HERE
   }
   else return nullptr;
}

That pointer is passed to here dump.cpp:

bool MemoryDump :: write(pos_t position, const void* s /*HERE*/, pos_t length)
{
   if (position <= _used) {
      resize(position + length); ///!!!<<< but _buffer can be reallocated here and invalidate the parameter "s"

      memcpy(static_cast<char*>(_buffer) + position, s, length);

      return true;
   }
   else return false;

}

The parameter s is a pointer inside _buffer that can be reallocated in resize(position + length); and became invalid (use after free).

We are copying part of itself over itself, quick dirty fix can be to strdup the return of node.identifier() and free it after.

I've tested with this:

      static void copyNewNode(SyntaxTreeWriter& writer, SyntaxNode node)
      {
         if (node.arg.strArgPosition != INVALID_POS) {
            char *id = strdup(node.identifier());
            writer.newNode(node.key, id);
            free(id);
         }
         else writer.newNode(node.key, node.arg.reference);
      }

And no valgrind warnings anymore (although there is other problems).

==16922== Memcheck, a memory error detector
==16922== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==16922== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==16922== Command: ../../bin/elena64-cli ../../src60/system/system.project
==16922== 
ELENA Command-line compiler 6.5.91 (C)2005-2024 by Aleksey Rakov, ELENA-LANG Org

Project: system, Platform: Linux_AMD64, Target type: Library
Cleaning up
Parsing attributes/attributes.l
Compiling system'attributes
saving system'attributes
Parsing predefined/predefined.l
Parsing predefined/aliases.l
Compiling system'predefined
saving system'predefined
Parsing operations/inline.l
Parsing operations/operations.l
Compiling system'operations
saving system'operations
Parsing operations/advanced/operations.l
Compiling system'operations'advanced
saving system'operations'advanced
Parsing inline_templates.l
Parsing object.l
Parsing basic.l
Parsing variables.l
Parsing primitives.l
Parsing enumerables.l
Parsing strings.l
Parsing extensions.l
Parsing messaging.l
Parsing closures.l
Parsing convertors.l
Parsing pointers.l
Parsing lnx_primitives.l
Parsing dynamic.l
Parsing exceptions.l
Parsing events.l
Parsing console.l
Parsing app.l
Parsing lnx_app.l
Parsing lnx_strings.l
Parsing template_tests.l
Parsing collections/list.l
Parsing collections/queues.l
Parsing collections/tuples.l
Parsing collections/maps.l
Parsing collections/sorted_list.l
Parsing collections/template_tests.l
Parsing math/math.l
Parsing text/encoding.l
Parsing text/textbuffer.l
Parsing io/common.l
Parsing io/streamreader.l
Parsing io/streamwriter.l
Parsing io/lnx_console.l
Parsing io/files.l
Parsing io/ioexceptions.l
Parsing io/lnx_files.l
Parsing io/lnx_getfiles.l
Parsing calendar/lnx64_datetime.l
Parsing calendar/dates.l
Compiling system......
info 701:   new method read<'$auto'system@Array#1&system@ByteNumber,'$auto'system@Reference#1&system@IntNumber>[3]

io/lnx_files.l(42:7): error 142: new method cannot be declared
Compiled with errors
==16922== 
==16922== HEAP SUMMARY:
==16922==     in use at exit: 85,257 bytes in 65 blocks
==16922==   total heap usage: 799,906 allocs, 799,841 frees, 174,596,923,879 bytes allocated
==16922== 
==16922== LEAK SUMMARY:
==16922==    definitely lost: 12,553 bytes in 64 blocks
==16922==    indirectly lost: 0 bytes in 0 blocks
==16922==      possibly lost: 0 bytes in 0 blocks
==16922==    still reachable: 72,704 bytes in 1 blocks
==16922==         suppressed: 0 bytes in 0 blocks
==16922== Rerun with --leak-check=full to see details of leaked memory
==16922== 
==16922== For lists of detected and suppressed errors, rerun with: -s
==16922== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==17081== Memcheck, a memory error detector
==17081== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==17081== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==17081== Command: ../../bin/elena64-cli ../../src60/extensions/extensions.project
==17081== 
ELENA Command-line compiler 6.5.91 (C)2005-2024 by Aleksey Rakov, ELENA-LANG Org

Project: extensions, Platform: Linux_AMD64, Target type: Library
Cleaning up
Parsing control.l
Parsing convertors.l
Parsing console.l
Parsing basic.l
Parsing tests.l
Parsing random.l
Parsing app.l
Parsing lnx_args.l
Parsing text/strings.l
Parsing text/words.l
Parsing math/functions.l
Parsing math/matrix.l
Compiling extensions
(1:8): warning 413: Unknown module 'system'

internal error 604: Base class doesn't exist
Compiled with errors
==17081== 
==17081== HEAP SUMMARY:
==17081==     in use at exit: 82,247 bytes in 56 blocks
==17081==   total heap usage: 70,131 allocs, 70,075 frees, 1,369,167,154 bytes allocated
==17081== 
==17081== LEAK SUMMARY:
==17081==    definitely lost: 9,543 bytes in 55 blocks
==17081==    indirectly lost: 0 bytes in 0 blocks
==17081==      possibly lost: 0 bytes in 0 blocks
==17081==    still reachable: 72,704 bytes in 1 blocks
==17081==         suppressed: 0 bytes in 0 blocks
==17081== Rerun with --leak-check=full to see details of leaked memory
==17081== 
==17081== For lists of detected and suppressed errors, rerun with: -s
==17081== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
mingodad commented 1 month ago

A better solution would be to have another newNode chain that accept a start position and end position something like:

void newNode(Key key, pos_t id_start, pos_t id_end)
arakov commented 1 month ago

Thanks for the help. I've fixed it. Please take a look and call your memory error detector again

As for the compiler error, it is already fixed in iteration34 branch. You can pull it. All the changes are there

arakov commented 1 month ago

Fixed in 6.4.4, the compiler for Linux will use the local config file if available.

Please let me know if it doesn't work for you. I will reopen issue in this case