From 100a3a3053d3010acf2867983ec14a7996cddb53 Mon Sep 17 00:00:00 2001 From: YairBybabayov Date: Sun, 25 Aug 2024 22:01:38 +0300 Subject: [PATCH 1/2] chached functions --- elenasrc3/elc/clicommon.h | 10 +++++++++- elenasrc3/elc/compilerlogic.cpp | 32 +++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/elenasrc3/elc/clicommon.h b/elenasrc3/elc/clicommon.h index 7c6a785e0..0df9cd33d 100644 --- a/elenasrc3/elc/clicommon.h +++ b/elenasrc3/elc/clicommon.h @@ -300,6 +300,10 @@ class ModuleScopeBase : public SectionScopeBase Map cachedClassReferences; Map cachedEmbeddableReadonlys; Map cachedEmbeddables; + Map cachedEmbeddableStructs; + Map cachedEmbeddableArrays; + Map cachedStacksafeArgs; + Map cachedWrappers; virtual bool isStandardOne() = 0; virtual bool withValidation() = 0; @@ -369,7 +373,11 @@ class ModuleScopeBase : public SectionScopeBase cachedSizes({}), cachedClassReferences(0), cachedEmbeddableReadonlys(false), - cachedEmbeddables(false) + cachedEmbeddables(false), + cachedEmbeddableStructs(false), + cachedEmbeddableArrays(false), + cachedStacksafeArgs(false), + cachedWrappers(false) { this->module = module; this->debugModule = debugModule; diff --git a/elenasrc3/elc/compilerlogic.cpp b/elenasrc3/elc/compilerlogic.cpp index 519184bd4..af989ed55 100644 --- a/elenasrc3/elc/compilerlogic.cpp +++ b/elenasrc3/elc/compilerlogic.cpp @@ -1306,9 +1306,16 @@ bool CompilerLogic :: isReadOnly(ClassInfo& info) bool CompilerLogic :: isEmbeddableArray(ModuleScopeBase& scope, ref_t reference) { + if (scope.cachedEmbeddableArrays.exist(reference)) + return scope.cachedEmbeddableArrays.get(reference); + ClassInfo info; if (defineClassInfo(scope, info, reference, true)) { - return isEmbeddableArray(info); + auto retVal = isEmbeddableArray(info); + + scope.cachedEmbeddableArrays.add(reference, retVal); + + return retVal; } return false; @@ -1388,10 +1395,15 @@ bool CompilerLogic :: isEmbeddableStruct(ModuleScopeBase& scope, TypeInfo typeIn if (typeInfo.nillable) return false; + if (scope.cachedEmbeddableStructs.exist(typeInfo.typeRef)) + return scope.cachedEmbeddableStructs.get(typeInfo.typeRef); + ClassInfo info; if (defineClassInfo(scope, info, typeInfo.typeRef, true)) { auto retVal = isEmbeddableStruct(info); + scope.cachedEmbeddableStructs.add(typeInfo.typeRef, retVal); + return retVal; } @@ -1408,9 +1420,16 @@ bool CompilerLogic :: isStacksafeArg(ClassInfo& info) bool CompilerLogic :: isStacksafeArg(ModuleScopeBase& scope, ref_t reference) { + if (scope.cachedStacksafeArgs.exist(reference)) + return scope.cachedStacksafeArgs.get(reference); + ClassInfo info; if (defineClassInfo(scope, info, reference, true)) { - return isStacksafeArg(info); + auto retVal = isStacksafeArg(info); + + scope.cachedStacksafeArgs.add(reference, retVal); + + return retVal; } return false; @@ -1418,9 +1437,16 @@ bool CompilerLogic :: isStacksafeArg(ModuleScopeBase& scope, ref_t reference) bool CompilerLogic :: isWrapper(ModuleScopeBase& scope, ref_t reference) { + if (scope.cachedWrappers.exist(reference)) + return scope.cachedWrappers.get(reference); + ClassInfo info; if (defineClassInfo(scope, info, reference, true)) { - return isWrapper(info); + auto retVal = isWrapper(info); + + scope.cachedWrappers.add(reference, retVal); + + return retVal; } return false; From 773628349206a261277002f373863de70daf37d1 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Wed, 4 Sep 2024 15:24:08 +0200 Subject: [PATCH 2/2] Iteration31 (#687) * [FIXED] method reference : support function singletons * [ADDED] Thread: Priority * [FIXED] direct typecasting must have priority over implicit conversion * [FIXED]if there is a general single dispatch operation -> use direct call * [API][ADDED] Thread: Priority, Join * [ELC][ADDED] new option -el5 / -el6 (default) - specifying grammar compatible to ELENA 5.x or 6.x * working on Win x32-64 : MTA Console * [ADDED] new byte-codes : peektls / storetls * [ADDED] Thread static symbols / static fields * fixing ?? operator * adding ?? functional tests * fixing x86 MTA * optimizing createnr opcode implementation * [ADDED]x86-64 : mta - ntlinker64 * [IDE][FIXED] #679 : class already exist * [ADDED]Thread.sleep * x86-64 : working on MTA * [ADDED] static constructor * [ADDED] system'runtime'Environment * [ADDED] system'collections'threadsafe'ThreadSafeQueue * [ADDED] #154 : system'threading'Semaphore * [ADDED] system'threading'BlockingQueue * [ADDED]system'threading'ThreadPool * [ADDED] internal symbols --- .github/workflows/msbuild.yml | 10 +- VERSION | 2 +- asm/aarch64/core60.asm | 11 + asm/amd64/core60.asm | 104 +- asm/amd64/core60_lnx.asm | 30 +- asm/amd64/corex60.asm | 588 ++++++ asm/amd64/corex60_win.asm | 19 + asm/ppc64le/core60.asm | 11 + asm/x32/core60.asm | 185 +- asm/x32/corex60.asm | 295 +-- bin/elc60.cfg | 1 + bin/templates/mt_win_console60.cfg | 6 +- build/aarch64/build_package_arm64.script | 2 +- build/aarch64/control | 2 +- build/amd64/build_package_amd64.script | 2 +- build/amd64/control | 2 +- build/elena_inno.iss | 4 +- build/i386/build_package_i386.script | 2 +- build/i386/control | 2 +- build/ppc64le/build_package_ppc64le.script | 2 +- build/ppc64le/control | 2 +- build/rebuild_data60_x64.bat | 53 + build/rebuild_data60_x86.bat | 53 + build/rebuild_lib60_x64.bat | 17 +- build/rebuild_lib60_x86.bat | 20 +- dat/api2html/api2html.bat | 1 + dat/sg/syntax50.txt | 936 +++++++++ dat/sg/syntax60.txt | 22 +- doc/api/algorithms-summary.html | 6 +- doc/api/algorithms.html | 6 +- doc/api/cellular-summary.html | 6 +- doc/api/cellular.html | 6 +- doc/api/extensions-dynamic-summary.html | 6 +- doc/api/extensions-dynamic.html | 6 +- doc/api/extensions-io-summary.html | 32 +- doc/api/extensions-io.html | 434 +---- doc/api/extensions-routines-summary.html | 6 +- doc/api/extensions-routines.html | 6 +- doc/api/extensions-scripting-summary.html | 6 +- doc/api/extensions-scripting.html | 6 +- doc/api/extensions-summary.html | 9 - doc/api/extensions.html | 70 +- doc/api/forms-summary.html | 6 +- doc/api/forms.html | 6 +- doc/api/index.html | 56 +- doc/api/ltests-summary.html | 6 +- doc/api/ltests.html | 6 +- doc/api/net-summary.html | 6 +- doc/api/net.html | 6 +- doc/api/system-collections-summary.html | 63 +- ...system-collections-threadsafe-summary.html | 164 ++ doc/api/system-collections-threadsafe.html | 1725 +++++++++++++++++ doc/api/system-collections.html | 997 ---------- doc/api/system-culture-summary.html | 3 +- doc/api/system-culture.html | 3 +- doc/api/system-drawing-summary.html | 6 +- doc/api/system-drawing.html | 6 +- .../system-dynamic-expressions-summary.html | 6 +- doc/api/system-dynamic-expressions.html | 6 +- doc/api/system-dynamic-summary.html | 6 +- doc/api/system-dynamic.html | 6 +- doc/api/system-io-summary.html | 54 - doc/api/system-io.html | 1634 ++++------------ doc/api/system-math-summary.html | 29 - doc/api/system-math.html | 74 - doc/api/system-net-summary.html | 6 +- doc/api/system-net.html | 6 +- doc/api/system-routines-summary.html | 6 +- doc/api/system-routines.html | 6 +- doc/api/system-runtime-summary.html | 97 +- doc/api/system-runtime.html | 332 +++- doc/api/system-summary.html | 137 +- doc/api/system-text-summary.html | 26 +- doc/api/system-text.html | 371 +--- doc/api/system-threading-summary.html | 95 +- doc/api/system-threading.html | 671 ++++++- doc/api/system-winforms-summary.html | 6 +- doc/api/system-winforms.html | 6 +- doc/api/system.html | 809 +------- doc/contributors | 2 +- doc/features | 81 + doc/tech/bytecode60.txt | 2 - doc/todo.txt | 25 +- elenasrc3/common/common.h | 1 + elenasrc3/common/tree.h | 30 + elenasrc3/elc/clicommon.h | 21 +- elenasrc3/elc/cliconst.h | 11 +- elenasrc3/elc/compiler.cpp | 235 ++- elenasrc3/elc/compiler.h | 11 +- elenasrc3/elc/compilerlogic.cpp | 43 +- elenasrc3/elc/compilerlogic.h | 5 +- elenasrc3/elc/compiling.cpp | 82 +- elenasrc3/elc/compiling.h | 6 +- elenasrc3/elc/derivation.cpp | 1 + elenasrc3/elc/errors.h | 1 + elenasrc3/elc/linux/elc.cpp | 2 +- elenasrc3/elc/messages.h | 3 +- elenasrc3/elc/project.h | 12 + elenasrc3/elc/source.cpp | 4 +- elenasrc3/elc/windows/elc.cpp | 13 +- elenasrc3/elc/windows/ntimage.cpp | 20 +- elenasrc3/elc/windows/ntlinker64.cpp | 14 +- elenasrc3/elena-tests/bt_optimization.cpp | 42 +- elenasrc3/elena-tests/bt_optimization.h | 6 + elenasrc3/elena-tests/build_tests.cpp | 5 + elenasrc3/elena-tests/constructor_tests.cpp | 4 +- elenasrc3/elena-tests/declaration.cpp | 2 +- elenasrc3/elena-tests/elena-tests.vcxproj | 8 +- elenasrc3/elena-tests/tests_common.cpp | 22 +- elenasrc3/elenart/elenartmachine.cpp | 6 +- elenasrc3/elenart/elenartmachine.h | 2 +- elenasrc3/elenart/rtcommon.h | 2 +- elenasrc3/elenart/windows/dllmain.cpp | 13 +- elenasrc3/engine/bcwriter.cpp | 42 +- elenasrc3/engine/buildtree.h | 8 +- elenasrc3/engine/bytecode.cpp | 2 +- elenasrc3/engine/bytecode.h | 2 + elenasrc3/engine/codescope.cpp | 5 + elenasrc3/engine/codescope.h | 2 + elenasrc3/engine/core.h | 3 +- elenasrc3/engine/elena.h | 4 +- elenasrc3/engine/elenaconst.h | 11 + elenasrc3/engine/elenamachine.cpp | 4 +- elenasrc3/engine/elenamachine.h | 2 +- elenasrc3/engine/gcroutines.cpp | 4 +- elenasrc3/engine/jitcompiler.cpp | 60 +- elenasrc3/engine/jitcompiler.h | 7 +- elenasrc3/engine/jitlinker.cpp | 46 +- elenasrc3/engine/jitlinker.h | 2 + elenasrc3/engine/langcommon.h | 2 + elenasrc3/engine/syntaxtree.h | 1 + elenasrc3/engine/windows/winroutines.cpp | 4 +- elenasrc3/engine/x86helper.h | 8 +- elenasrc3/engine/x86relocation.h | 5 +- elenasrc3/ide/idecontroller.cpp | 13 +- elenasrc3/ide/ideversion.h | 2 +- elenasrc3/ide/windows/winide.cpp | 1 - elenasrc3/tools/asmc/asmconst.h | 2 +- elenasrc3/tools/asmc/x86assembler.cpp | 46 + elenasrc3/tools/asmc/x86assembler.h | 1 + elenasrc3/tools/ecv/ecviewer.cpp | 3 + elenasrc3/tools/ldoc/ldoc.cpp | 59 - elenasrc3/tools/ldoc/ldocconst.h | 4 +- examples60/threads/threadpool/sample1.l | 24 + examples60/threads/threadpool/threadpool.l | 9 + .../threads/threadpool/threadpoolsamples.prj | 14 + recompile60.bat | 29 +- src60/core/system.core_routines.esm | 10 +- src60/extensions/basic.l | 13 + src60/extensions/tests.l | 17 +- src60/extensions/threading/threading.l | 2 +- src60/system/attributes/attributes.l | 2 +- src60/system/collections/threadsafe/queues.l | 113 ++ .../collections/threadsafe/template_tests.l | 7 + src60/system/pointers.l | 5 +- src60/system/primitives.l | 2 +- src60/system/runtime/common.l | 8 +- src60/system/runtime/env.l | 16 + src60/system/runtime/win32_env.l | 59 + src60/system/system.prj | 10 + src60/system/threading/blockinglists.l | 27 + src60/system/threading/common.l | 3 + src60/system/threading/thread.l | 120 +- src60/system/threading/threadpool.l | 35 + src60/system/threading/win32_handlers.l | 91 +- src60/system/threading/win32_semaphores.l | 29 + tests60/sandbox/sandbox.l | 33 +- tests60/system_tests/basic.l | 21 +- 168 files changed, 7108 insertions(+), 5120 deletions(-) create mode 100644 asm/amd64/corex60.asm create mode 100644 asm/amd64/corex60_win.asm create mode 100644 build/rebuild_data60_x64.bat create mode 100644 build/rebuild_data60_x86.bat create mode 100644 dat/sg/syntax50.txt create mode 100644 doc/api/system-collections-threadsafe-summary.html create mode 100644 doc/api/system-collections-threadsafe.html create mode 100644 examples60/threads/threadpool/sample1.l create mode 100644 examples60/threads/threadpool/threadpool.l create mode 100644 examples60/threads/threadpool/threadpoolsamples.prj create mode 100644 src60/system/collections/threadsafe/queues.l create mode 100644 src60/system/collections/threadsafe/template_tests.l create mode 100644 src60/system/runtime/env.l create mode 100644 src60/system/runtime/win32_env.l create mode 100644 src60/system/threading/blockinglists.l create mode 100644 src60/system/threading/common.l create mode 100644 src60/system/threading/threadpool.l create mode 100644 src60/system/threading/win32_semaphores.l diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 68541854d..744b172d5 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -20,7 +20,7 @@ env: # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix BUILD_CONFIGURATION: Release - BUILD_TAG: 6.3.0 + BUILD_TAG: 6.3.1 permissions: contents: read @@ -52,6 +52,14 @@ jobs: # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} /p:platform=${{ matrix.platform }} /m:2 + - name: Generate Data + shell: cmd + run: build\rebuild_data60_${{matrix.platform}}.bat + + - name: Run Tests + shell: cmd + run: bin\elena-tests-${{matrix.platform}}.exe + - name: Compile Lib shell: cmd run: build\rebuild_lib60_${{matrix.platform}}.bat diff --git a/VERSION b/VERSION index e7e42a4b5..39ee137ba 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.3.0 \ No newline at end of file +6.3.1 \ No newline at end of file diff --git a/asm/aarch64/core60.asm b/asm/aarch64/core60.asm index c64f74ca5..463f2c4c5 100644 --- a/asm/aarch64/core60.asm +++ b/asm/aarch64/core60.asm @@ -113,6 +113,7 @@ end // ; NOTE : the table is tailed with GCMGSize,GCYGSize and MaxThread fields structure %SYSTEM_ENV + dq 0 dq 0 dq data : %CORE_GC_TABLE dq data : %CORE_SINGLE_CONTENT @@ -2149,6 +2150,16 @@ labEnd: end +// ; peektls +inline %0BBh + +end + +// ; storetls +inline %0BCh + +end + // ; cmpr inline %0C0h diff --git a/asm/amd64/core60.asm b/asm/amd64/core60.asm index af003378e..40693376f 100644 --- a/asm/amd64/core60.asm +++ b/asm/amd64/core60.asm @@ -113,6 +113,7 @@ end // ; NOTE : the table is tailed with GCMGSize,GCYGSize and MaxThread fields structure %SYSTEM_ENV + dq 0 dq 0 dq data : %CORE_GC_TABLE dq data : %CORE_SINGLE_CONTENT @@ -160,90 +161,16 @@ inline % GC_ALLOC labYGCollect: // ; save registers sub rcx, rax - push r10 - push r11 - push rbp - - // ; lock frame - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], rsp - - push rcx - - // ; create set of roots - mov rbp, rsp - xor ecx, ecx - push rcx // ; reserve place - push rcx - push rcx - - // ; save static roots - mov rax, rdata : %SYSTEM_ENV - mov rsi, stat : %0 - mov ecx, dword ptr [rax] - shl ecx, 3 - push rsi - push rcx - - // ; save perm roots - mov rsi, [data : %CORE_GC_TABLE + gc_perm_start] - mov rcx, [data : %CORE_GC_TABLE + gc_perm_current] - sub rcx, rsi - push rsi - push rcx - - // ; collect frames - mov rax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] - mov rcx, rax - -labYGNextFrame: - mov rsi, rax - mov rax, [rsi] - test rax, rax - jnz short labYGNextFrame - - push rcx - sub rcx, rsi - neg rcx - push rcx - - mov rax, [rsi + 8] - test rax, rax - mov rcx, rax - jnz short labYGNextFrame - - mov [rbp-8], rsp // ; save position for roots - - mov rdx, [rbp] - mov rcx, rsp - - // ; restore frame to correctly display a call stack - mov rax, rbp - mov rbp, [rax+8] - - // ; call GC routine - sub rsp, 30h - mov [rsp+28h], rax - call extern "$rt.CollectGCLA" - - mov rbp, [rsp+28h] - add rsp, 30h - mov rbx, rax - - mov rsp, rbp - pop rcx - pop rbp - pop r11 - pop r10 - + xor edx, edx + call %GC_COLLECT ret end // ; --- GC_COLLECT --- -// ; in: ecx - fullmode (0, 1) +// ; in: ecx - size, edx - 1 - full collect, 0 - normal one inline % GC_COLLECT - // ; save registers push r10 push r11 push rbp @@ -251,12 +178,14 @@ inline % GC_COLLECT // ; lock frame mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], rsp + push rdx push rcx // ; create set of roots mov rbp, rsp xor ecx, ecx push rcx // ; reserve place + push rcx push rcx push rcx @@ -268,6 +197,13 @@ inline % GC_COLLECT push rsi push rcx + // ; save perm roots + mov rsi, [data : %CORE_GC_TABLE + gc_perm_start] + mov rcx, [data : %CORE_GC_TABLE + gc_perm_current] + sub rcx, rsi + push rsi + push rcx + // ; collect frames mov rax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] mov rcx, rax @@ -290,12 +226,13 @@ labYGNextFrame: mov [rbp-8], rsp // ; save position for roots + mov r8, [rbp+8] mov rdx, [rbp] mov rcx, rsp // ; restore frame to correctly display a call stack mov rax, rbp - mov rbp, [rax+8] + mov rbp, [rax+16] // ; call GC routine sub rsp, 30h @@ -308,6 +245,7 @@ labYGNextFrame: mov rsp, rbp pop rcx + pop rdx pop rbp pop r11 pop r10 @@ -1844,6 +1782,16 @@ labEnd: end +// ; peektls +inline %0BBh + +end + +// ; storetls +inline %0BCh + +end + // ; cmpr r inline %0C0h diff --git a/asm/amd64/core60_lnx.asm b/asm/amd64/core60_lnx.asm index ff8cebcbc..cb8578514 100644 --- a/asm/amd64/core60_lnx.asm +++ b/asm/amd64/core60_lnx.asm @@ -84,23 +84,10 @@ procedure % VEH_HANDLER end -// ; --- GC_ALLOC --- -// ; in: rcx - size ; out: ebx - created object -// ; note for linux - there is a separate copy -inline % GC_ALLOC - - mov rax, [data : %CORE_GC_TABLE + gc_yg_current] - mov r12, [data : %CORE_GC_TABLE + gc_yg_end] - add rcx, rax - cmp rcx, r12 - jae short labYGCollect - mov [data : %CORE_GC_TABLE + gc_yg_current], rcx - lea rbx, [rax + elObjectOffset] - ret +// ; --- GC_COLLECT --- +// ; in: ecx - size, edx - 1 - full collect, 0 - normal one +inline % GC_COLLECT -labYGCollect: - // ; save registers - sub rcx, rax push r10 push r11 push rbp @@ -108,12 +95,14 @@ labYGCollect: // ; lock frame mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], rsp + push rdx push rcx // ; create set of roots mov rbp, rsp xor ecx, ecx push rcx // ; reserve place + push rcx push rcx push rcx @@ -125,6 +114,13 @@ labYGCollect: push rsi push rcx + // ; save perm roots + mov rsi, [data : %CORE_GC_TABLE + gc_perm_start] + mov rcx, [data : %CORE_GC_TABLE + gc_perm_current] + sub rcx, rsi + push rsi + push rcx + // ; collect frames mov rax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] mov rcx, rax @@ -147,6 +143,7 @@ labYGNextFrame: mov [rbp-8], rsp // ; save position for roots + mov rdx, [rbp+8] mov rsi, [rbp] mov rdi, rsp @@ -165,6 +162,7 @@ labYGNextFrame: mov rsp, rbp pop rcx + pop rdx pop rbp pop r11 pop r10 diff --git a/asm/amd64/corex60.asm b/asm/amd64/corex60.asm new file mode 100644 index 000000000..33d1ba011 --- /dev/null +++ b/asm/amd64/corex60.asm @@ -0,0 +1,588 @@ +// !! NOTE : R15 register must be preserved + +// ; --- Predefined References -- +define INVOKER 10001h +define GC_ALLOC 10002h +define VEH_HANDLER 10003h +define GC_COLLECT 10004h +define GC_ALLOCPERM 10005h +define PREPARE 10006h +define THREAD_WAIT 10007h + +define CORE_TOC 20001h +define SYSTEM_ENV 20002h +define CORE_GC_TABLE 20003h +define CORE_TLS_INDEX 20004h +define CORE_SINGLE_CONTENT 2000Bh +define VOID 2000Dh +define VOIDPTR 2000Eh +define CORE_THREAD_TABLE 2000Fh + +define ACTION_ORDER 9 +define ACTION_MASK 1E0h +define ARG_MASK 01Fh +define ARG_ACTION_MASK 1DFh + +// ; --- Object header fields --- +define elSizeOffset 0004h +define elVMTOffset 0010h +define elObjectOffset 0010h + +// ; --- VMT header fields --- +define elVMTSizeOffset 0008h +define elVMTFlagOffset 0018h +define elPackageOffset 0020h + +// ; --- sysenv offsets --- +define env_tls_size 0008h + +// ; --- GC TABLE OFFSETS --- +define gc_header 0000h +define gc_start 0008h +define gc_yg_start 0010h +define gc_yg_current 0018h +define gc_yg_end 0020h +define gc_mg_start 0038h +define gc_mg_current 0040h +define gc_end 0048h +define gc_mg_wbar 0050h +define gc_perm_start 0058h +define gc_perm_end 0060h +define gc_perm_current 0068h +define gc_lock 0070h +define gc_signal 0078h + +// ; THREAD CONTENT +define et_current 0008h +define tt_stack_frame 0010h +define tt_sync_event 0018h +define tt_flags 0020h +define tt_stack_root 0028h + +define tt_size 0030h + +define es_prev_struct 0000h +define es_catch_addr 0008h +define es_catch_level 0010h +define es_catch_frame 0018h + +// ; THREAD TABLE +define tt_slots 00008h + +// ; --- Page Size ---- +define page_ceil 2Fh +define page_mask 0FFFFFFE0h +define page_size_order 5h +define struct_mask 40000000h +define struct_mask_inv 3FFFFFFFh + +// ; NOTE : the table is tailed with GCMGSize,GCYGSize and MaxThread fields +structure %SYSTEM_ENV + + dq 0 + dq 0 + dq data : %CORE_GC_TABLE + dq 0 + dq data : %CORE_THREAD_TABLE + dq code : %INVOKER + dq code : %VEH_HANDLER + // ; dd GCMGSize + // ; dd GCYGSize + // ; dd ThreadCounter + +end + +structure %CORE_THREAD_TABLE + + dq 0 // ; tt_length : +00h + + dq 0 // ; tt_slots : +08h + dq 0 + +end + +// ; --- GC_ALLOC --- +// ; in: ecx - size ; out: ebx - created object +inline % GC_ALLOC + + // ; GCXT: set lock +labStart: + mov rdi, data : %CORE_GC_TABLE + gc_lock + +labWait: + mov edx, 1 + xor eax, eax + lock cmpxchg dword ptr[rdi], edx + jnz short labWait + + mov rax, [data : %CORE_GC_TABLE + gc_yg_current] + mov r12, [data : %CORE_GC_TABLE + gc_yg_end] + add rcx, rax + cmp rcx, r12 + jae short labYGCollect + mov [data : %CORE_GC_TABLE + gc_yg_current], rcx + + // ; GCXT: clear sync field + mov edx, 0FFFFFFFFh + lea rbx, [rax + elObjectOffset] + + // ; GCXT: free lock + // ; could we use mov [esi], 0 instead? + lock xadd [rdi], edx + + ret + +labYGCollect: + // ; save registers + sub rcx, rax + xor edx, edx + call %GC_COLLECT + ret + +end + +// ; --- GC_COLLECT --- +// ; in: ecx - fullmode (0, 1) +inline % GC_COLLECT + +labStart: + // ; GCXT: find the current thread entry + mov rdi, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + + push r10 + push r11 + + // ; GCXT: find the current thread entry + mov rax, [rdi+rax*8] + + push rbp + + // ; GCXT: lock frame + // ; get current thread event + mov rsi, [rax + tt_sync_event] + mov [rax + tt_stack_frame], rsp + + push rdx + push rcx + + // ; === GCXT: safe point === + mov rdx, [data : %CORE_GC_TABLE + gc_signal] + // ; if it is a collecting thread, starts the GC + test rdx, rdx + jz short labConinue + // ; otherwise eax contains the collecting thread event + + sub rsp, 30h + + // ; signal the collecting thread that it is stopped + mov r12, rdx + + mov rcx, rsi + call extern "$rt.SignalStopGCLA" + + // ; free lock + // ; could we use mov [esi], 0 instead? + mov rdi, data : %CORE_GC_TABLE + gc_lock + mov ebx, 0FFFFFFFFh + lock xadd [rdi], ebx + + // ; stop until GC is ended + mov rcx, r12 + call extern "$rt.WaitForSignalGCLA" + add rsp, 30h + // ; restore registers and try again + + pop rcx + pop rdx + pop rbp + pop r11 + pop r10 + + test rcx, rcx + jz labStart + + // ; repeat the alloc operation if required + call %GC_ALLOC + ret + +labConinue: + mov [data : %CORE_GC_TABLE + gc_signal], rsi // set the collecting thread signal + mov rbp, rsp + + // ; === thread synchronization === + + // ; create list of threads need to be stopped + mov rax, rsi + // ; get tls entry address + mov rsi, data : %CORE_THREAD_TABLE + tt_slots + xor ecx, ecx + mov rdi, [rsi - 8] +labNext: + mov rdx, [rsi] + test rdx, rdx + jz short labSkipTT + cmp rax, [rdx + tt_sync_event] + setz cl + or ecx, dword ptr [rdx + tt_flags] + test ecx, 1 + // ; skip current thread signal / thread in safe region from wait list + jnz short labSkipSave + push [rdx + tt_sync_event] +labSkipSave: + + // ; reset all signal events + sub rsp, 30h + mov rcx, [rdx + tt_sync_event] + call extern "$rt.SignalClearGCLA" + add rsp, 30h + + lea rsi, [rsi + 16] + mov rax, [data : %CORE_GC_TABLE + gc_signal] +labSkipTT: + sub edi, 1 + jnz short labNext + + mov rsi, data : %CORE_GC_TABLE + gc_lock + mov edx, 0FFFFFFFFh + mov rbx, rbp + + // ; free lock + // ; could we use mov [esi], 0 instead? + lock xadd [rsi], edx + + mov rdx, rsp + sub rbx, rsp + jz short labSkipWait + + // ; wait until they all stopped + shr ebx, 3 + sub rsp, 30h + mov ecx, ebx + call extern "$rt.WaitForSignalsGCLA" + add rsp, 30h + +labSkipWait: + // ; remove list + mov rsp, rbp + + // ==== GCXT end ============== + + // ; create set of roots + mov rbp, rsp + xor ecx, ecx + push rcx // ; reserve place + push rcx + push rcx + push rcx + + // ; save static roots + mov rax, rdata : %SYSTEM_ENV + mov rsi, stat : %0 + mov ecx, dword ptr [rax] + shl ecx, 3 + push rsi + push rcx + + // ; save perm roots + mov rsi, [data : %CORE_GC_TABLE + gc_perm_start] + mov rcx, [data : %CORE_GC_TABLE + gc_perm_current] + sub rcx, rsi + push rsi + push rcx + + // ; == GCXT: save frames == + mov rax, data : %CORE_THREAD_TABLE + mov rbx, [rax] + +labYGNextThread: + sub ebx, 1 + mov rax, data : %CORE_THREAD_TABLE + tt_slots + + // ; get tls entry address + mov r8, rbx + shl r8, 4 + add r8, rax + mov rsi, [r8] + test rsi, rsi + jz short labYGNextThreadSkip + + // ; get the thread local roots + lea rax, [rsi + tt_size] + mov rcx, [rdata : %SYSTEM_ENV + env_tls_size] + push rax + push rcx + + // ; get the top frame pointer + mov rax, [rsi + tt_stack_frame] + mov rcx, rax + +labYGNextFrame: + mov rsi, rax + mov rax, [rsi] + test rax, rax + jnz short labYGNextFrame + + push rcx + sub rcx, rsi + neg rcx + push rcx + + mov rax, [rsi + 8] + test rax, rax + mov rcx, rax + jnz short labYGNextFrame + nop + nop + +labYGNextThreadSkip: + test rbx, rbx + jnz short labYGNextThread + // ; == GCXT: end == + + mov [rbp-8], rsp // ; save position for roots + + mov r8, [rbp+8] + mov rdx, [rbp] + mov rcx, rsp + + // ; restore frame to correctly display a call stack + mov rax, rbp + mov rbp, [rax+16] + + // ; call GC routine + sub rsp, 30h + mov [rsp+28h], rax + call extern "$rt.CollectGCLA" + + mov rbp, [rsp+28h] + mov rdi, rax + + mov rbp, [rsp+28h] + + // ; GCXT: signal the collecting thread that GC is ended + // ; should it be placed into critical section? + xor ebx, ebx + mov rcx, [data : %CORE_GC_TABLE + gc_signal] + // ; clear thread signal var + mov [data : %CORE_GC_TABLE + gc_signal], rbx + call extern "$rt.SignalStopGCLA" + + add rsp, 30h + + mov rbx, rdi + + mov rsp, rbp + pop rcx + pop rdx + pop rbp + pop r11 + pop r10 + + ret + +end + +// --- GC_ALLOCPERM --- +// in: ecx - size ; out: ebx - created object +procedure %GC_ALLOCPERM + +labStart: + // ; GCXT: find the current thread entry + mov rdi, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + + push r10 + push r11 + + // ; GCXT: find the current thread entry + mov rax, [rdi+rax*8] + + push rbp + + // ; GCXT: lock frame + // ; get current thread event + mov rsi, [rax + tt_sync_event] + mov [rax + tt_stack_frame], rsp + + push rdx + push rcx + + // ; === GCXT: safe point === + mov rdx, [data : %CORE_GC_TABLE + gc_signal] + // ; if it is a collecting thread, starts the GC + test rdx, rdx + jz short labConinue + // ; otherwise eax contains the collecting thread event + + sub rsp, 30h + + // ; signal the collecting thread that it is stopped + mov r12, rdx + + mov rcx, rsi + call extern "$rt.SignalStopGCLA" + + // ; free lock + // ; could we use mov [esi], 0 instead? + mov rdi, data : %CORE_GC_TABLE + gc_lock + mov ebx, 0FFFFFFFFh + lock xadd [rdi], ebx + + // ; stop until GC is ended + mov rcx, r12 + call extern "$rt.WaitForSignalGCLA" + add rsp, 30h + // ; restore registers and try again + + pop rcx + pop rdx + pop rbp + pop r11 + pop r10 + + test rcx, rcx + jz labStart + + // ; repeat the alloc operation if required + call %GC_ALLOC + ret + +labConinue: + mov [data : %CORE_GC_TABLE + gc_signal], rsi // set the collecting thread signal + mov rbp, rsp + + // ; === thread synchronization === + + // ; create list of threads need to be stopped + mov rax, rsi + // ; get tls entry address + mov rsi, data : %CORE_THREAD_TABLE + tt_slots + xor ecx, ecx + mov rdi, [rsi - 8] +labNext: + mov rdx, [rsi] + test rdx, rdx + jz short labSkipTT + cmp rax, [rdx + tt_sync_event] + setz cl + or ecx, dword ptr [rdx + tt_flags] + test ecx, 1 + // ; skip current thread signal / thread in safe region from wait list + jnz short labSkipSave + push [rdx + tt_sync_event] +labSkipSave: + + // ; reset all signal events + sub rsp, 30h + mov rcx, [rdx + tt_sync_event] + call extern "$rt.SignalClearGCLA" + add rsp, 30h + + lea rsi, [rsi + 16] + mov rax, [data : %CORE_GC_TABLE + gc_signal] +labSkipTT: + sub edi, 1 + jnz short labNext + + mov rsi, data : %CORE_GC_TABLE + gc_lock + mov edx, 0FFFFFFFFh + mov rbx, rbp + + // ; free lock + // ; could we use mov [esi], 0 instead? + lock xadd [rsi], edx + + mov rdx, rsp + sub rbx, rsp + jz short labSkipWait + + // ; wait until they all stopped + shr ebx, 3 + sub rsp, 30h + mov ecx, ebx + call extern "$rt.WaitForSignalsGCLA" + add rsp, 30h + +labSkipWait: + // ; remove list + mov rsp, rbp + + // ==== GCXT end ============== + + sub rsp, 30h + + mov rcx, [rbp + 8] + call extern "$rt.CollectPermGCLA" + + mov rdi, rax + + // ; GCXT: signal the collecting thread that GC is ended + // ; should it be placed into critical section? + xor ebx, ebx + mov rcx, [data : %CORE_GC_TABLE + gc_signal] + // ; clear thread signal var + mov [data : %CORE_GC_TABLE + gc_signal], rbx + call extern "$rt.SignalStopGCLA" + + mov rbx, rdi + add rsp, 30h + + pop rbp + pop r11 + pop r10 + ret + +end + +// --- THREAD_WAIT --- +// GCXT: it is presumed that gc lock is on, edx - contains the collecting thread event handle + +procedure % THREAD_WAIT + + push rbp + mov rdi, rsp + + mov r12, rbx + mov r13, rdx // hHandle + + // ; set lock + mov rbx, data : %CORE_GC_TABLE + gc_lock +labWait: + mov edx, 1 + xor eax, eax + lock cmpxchg dword ptr[rbx], edx + jnz short labWait + + // ; find the current thread entry + mov rdi, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rax, [rdx+rax*8] + + mov rsi, [rax+tt_sync_event] // ; get current thread event + mov [rax+tt_stack_frame], rdi // ; lock stack frame + + // ; signal the collecting thread that it is stopped + sub rsp, 30h + mov rcx, rsi + mov rdi, data : %CORE_GC_TABLE + gc_lock + + // ; signal the collecting thread that it is stopped + call extern "$rt.SignalStopGCLA" + add rsp, 30h + + // ; free lock + // ; could we use mov [esi], 0 instead? + mov ebx, 0FFFFFFFFh + lock xadd [rdi], ebx + + // ; stop until GC is ended + mov rcx, r13 + call extern "$rt.WaitForSignalGCLA" + + pop rbp + mov rbx, r12 + + ret + +end diff --git a/asm/amd64/corex60_win.asm b/asm/amd64/corex60_win.asm new file mode 100644 index 000000000..1f87bc558 --- /dev/null +++ b/asm/amd64/corex60_win.asm @@ -0,0 +1,19 @@ +// ; --- Predefined References -- +define VEH_HANDLER 10003h + +define CORE_TLS_INDEX 20004h + +// ; ==== System commands === + +// VEH_HANDLER() +procedure % VEH_HANDLER + + mov esi, edx + mov edx, eax // ; set exception code + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rcx, [rcx+rax*8] + jmp [rcx] + +end diff --git a/asm/ppc64le/core60.asm b/asm/ppc64le/core60.asm index 4c587b001..540137483 100644 --- a/asm/ppc64le/core60.asm +++ b/asm/ppc64le/core60.asm @@ -137,6 +137,7 @@ end // ; NOTE : the table is tailed with GCMGSize,GCYGSize and MaxThread fields structure %SYSTEM_ENV + dq 0 dq 0 dq data : %CORE_GC_TABLE dq data : %CORE_SINGLE_CONTENT @@ -1984,6 +1985,16 @@ labEnd: end +// ; peektls +inline %0BBh + +end + +// ; storetls +inline %0BCh + +end + // ; cmpr inline %0C0h diff --git a/asm/x32/core60.asm b/asm/x32/core60.asm index 272ddc1f1..2143e7f6a 100644 --- a/asm/x32/core60.asm +++ b/asm/x32/core60.asm @@ -115,6 +115,7 @@ end // ; NOTE : the table is tailed with GCMGSize,GCYGSize and MaxThread fields structure %SYSTEM_ENV + dd 0 dd 0 dd data : %CORE_GC_TABLE dd data : %CORE_SINGLE_CONTENT @@ -158,14 +159,24 @@ inline % GC_ALLOC ret labYGCollect: - // ; save registers sub ecx, eax + xor edx, edx + call %GC_COLLECT + ret + +end + +// ; --- GC_COLLECT --- +// ; in: ecx - size, edx - 1 - full collect, 0 - normal one +inline % GC_COLLECT + push esi push ebp // ; lock frame mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], esp + push edx push ecx // ; create set of roots @@ -212,98 +223,26 @@ labYGNextFrame: mov [ebp-4], esp // ; save position for roots mov ebx, [ebp] + mov edx, [ebp+4] mov eax, esp // ; restore frame to correctly display a call stack - mov edx, ebp - mov ebp, [edx+4] + mov ecx, ebp + mov ebp, [ecx+8] // ; call GC routine - push edx - push ebx - push eax - call extern "$rt.CollectGCLA" - - mov ebp, [esp+8] - add esp, 12 - mov ebx, eax - - mov esp, ebp - pop ecx - pop ebp - pop esi - ret - -end - -// ; --- GC_COLLECT --- -// ; in: ecx - fullmode (0, 1) -inline % GC_COLLECT - - // ; save registers - push esi - push ebp - - // ; lock frame - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], esp - push ecx - - // ; create set of roots - mov ebp, esp - xor ecx, ecx - push ecx // ; reserve place - push ecx - push ecx - - // ; save static roots - mov ecx, [rdata : %SYSTEM_ENV] - mov esi, stat : %0 - shl ecx, 2 - push esi - push ecx - - // ; collect frames - mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] - mov ecx, eax - -labYGNextFrame: - mov esi, eax - mov eax, [esi] - test eax, eax - jnz short labYGNextFrame - - push ecx - sub ecx, esi - neg ecx - push ecx - - mov eax, [esi + 4] - test eax, eax - mov ecx, eax - jnz short labYGNextFrame - - mov [ebp-4], esp // ; save position for roots - - mov ebx, [ebp] - mov eax, esp - - // ; restore frame to correctly display a call stack - mov edx, ebp - mov ebp, [edx+4] - - // ; call GC routine push edx push ebx push eax - call extern "$rt.ForcedCollectGCLA" + call extern "$rt.CollectGCLA" - mov ebp, [esp+8] - add esp, 12 + mov ebp, [esp+12] mov ebx, eax mov esp, ebp pop ecx + pop edx pop ebp pop esi ret @@ -1891,6 +1830,16 @@ labEnd: end +// ; peektls +inline %0BBh + +end + +// ; storetls +inline %0BCh + +end + // ; cmpr r inline %0C0h @@ -2146,6 +2095,7 @@ end inline %1CFh xor ecx, ecx + xor edx, edx call %GC_COLLECT end @@ -2153,7 +2103,8 @@ end // ; system full collect inline %2CFh - mov ecx, 1 + xor ecx, ecx + mov edx, 1 call %GC_COLLECT end @@ -3649,6 +3600,80 @@ inline %0F7h end +// ; createnr 1,r +inline %2F7h + + mov eax, [esi] + mov ecx, page_ceil + add ecx, eax + and ecx, page_mask + call %GC_ALLOC + + mov ecx, [esi] + mov eax, __ptr32_2 + or ecx, struct_mask + mov [ebx - elVMTOffset], eax + mov [ebx - elSizeOffset], ecx + +end + +// ; createnr 2,r +inline %3F7h + + mov eax, [esi] + mov ecx, page_ceil + shl eax, 1 + add ecx, eax + and ecx, page_mask + call %GC_ALLOC + + mov ecx, [esi] + shl ecx, 1 + mov eax, __ptr32_2 + or ecx, struct_mask + mov [ebx - elVMTOffset], eax + mov [ebx - elSizeOffset], ecx + +end + +// ; createnr 4,r +inline %5F7h + + mov eax, [esi] + mov ecx, page_ceil + shl eax, 2 + add ecx, eax + and ecx, page_mask + call %GC_ALLOC + + mov ecx, [esi] + shl ecx, 2 + mov eax, __ptr32_2 + or ecx, struct_mask + mov [ebx - elVMTOffset], eax + mov [ebx - elSizeOffset], ecx + +end + +// ; createnr 8,r +inline %7F7h + + mov eax, [esi] + mov ecx, page_ceil + shl eax, 3 + add ecx, eax + and ecx, page_mask + call %GC_ALLOC + + mov ecx, [esi] + shl ecx, 3 + mov eax, __ptr32_2 + or ecx, struct_mask + mov [ebx - elVMTOffset], eax + mov [ebx - elSizeOffset], ecx + +end + // ; fillir inline % 0F8h diff --git a/asm/x32/corex60.asm b/asm/x32/corex60.asm index 1a6e9c335..f1daad09b 100644 --- a/asm/x32/corex60.asm +++ b/asm/x32/corex60.asm @@ -16,6 +16,9 @@ define VOID 2000Dh define VOIDPTR 2000Eh define CORE_THREAD_TABLE 2000Fh +// ; --- sysenv offsets --- +define env_tls_size 0004h + // ; --- GC TABLE OFFSETS --- define gc_header 0000h define gc_start 0004h @@ -41,6 +44,8 @@ define tt_sync_event 000Ch define tt_flags 0010h define tt_stack_root 0014h +define tt_size 0018h + define es_prev_struct 0000h define es_catch_addr 0004h define es_catch_level 0008h @@ -58,6 +63,7 @@ define elObjectOffset 0008h // ; NOTE : the table is tailed with GCMGSize,GCYGSize and MaxThread fields structure %SYSTEM_ENV + dd 0 dd 0 dd data : %CORE_GC_TABLE dd 0 @@ -67,6 +73,7 @@ structure %SYSTEM_ENV // ; dd GCMGSize // ; dd GCYGSize // ; dd ThreadCounter + // ; dd TLSSize end @@ -112,15 +119,25 @@ labWait: labYGCollect: // ; save registers sub ecx, eax + xor edx, edx + call %GC_COLLECT + ret + +end + +// ; --- GC_COLLECT --- +// ; in: ecx - fullmode (0, 1) +inline % GC_COLLECT +labStart: // ; GCXT: find the current thread entry - mov edx, fs:[2Ch] + mov edi, fs:[2Ch] mov eax, [data : %CORE_TLS_INDEX] push esi // ; GCXT: find the current thread entry - mov eax, [edx+eax*4] + mov eax, [edi+eax*4] push ebp @@ -129,6 +146,7 @@ labYGCollect: mov esi, [eax + tt_sync_event] mov [eax + tt_stack_frame], esp + push edx push ecx // ; === GCXT: safe point === @@ -156,10 +174,16 @@ labYGCollect: // ; restore registers and try again pop ecx + pop edx pop ebp pop esi - jmp labStart + test ecx, ecx + jz labStart + + // ; repeat the alloc operation if required + call %GC_ALLOC + ret labConinue: mov [data : %CORE_GC_TABLE + gc_signal], esi // set the collecting thread signal @@ -255,6 +279,12 @@ labYGNextThread: test esi, esi jz short labYGNextThreadSkip + // ; get the thread local roots + lea eax, [esi + tt_size] + mov ecx, [rdata : %SYSTEM_ENV + env_tls_size] + push eax + push ecx + // ; get the top frame pointer mov eax, [esi + tt_stack_frame] mov ecx, eax @@ -285,214 +315,22 @@ labYGNextThreadSkip: mov [ebp-4], esp // ; save position for roots mov ebx, [ebp] + mov edx, [ebp+4] mov eax, esp // ; restore frame to correctly display a call stack - mov edx, ebp - mov ebp, [edx+4] + mov ecx, ebp + mov ebp, [ecx+8] // ; call GC routine - push edx - push ebx - push eax - call extern "$rt.CollectGCLA" - - mov edi, eax - mov ebp, [esp+8] - add esp, 12 - - // ; GCXT: signal the collecting thread that GC is ended - // ; should it be placed into critical section? - xor ecx, ecx - mov esi, [data : %CORE_GC_TABLE + gc_signal] - // ; clear thread signal var - mov [data : %CORE_GC_TABLE + gc_signal], ecx - push esi - call extern "$rt.SignalStopGCLA" - - mov ebx, edi - - mov esp, ebp - pop ecx - pop ebp - pop esi - ret - -end - -// ; --- GC_COLLECT --- -// ; in: ecx - fullmode (0, 1) -inline % GC_COLLECT - - // ; GCXT: set lock -labStart: - mov edi, data : %CORE_GC_TABLE + gc_lock - -labWait: - mov edx, 1 - xor eax, eax - lock cmpxchg dword ptr[edi], edx - jnz short labWait - - // ; GCXT: find the current thread entry - mov edx, fs:[2Ch] - mov eax, [data : %CORE_TLS_INDEX] - - push esi - - // ; GCXT: find the current thread entry - mov eax, [edx+eax*4] - - push ebp - - // ; GCXT: lock frame - // ; get current thread event - mov esi, [eax + tt_sync_event] - mov [eax + tt_stack_frame], esp - push ecx - - // ; === GCXT: safe point === - mov edx, [data : %CORE_GC_TABLE + gc_signal] - // ; if it is a collecting thread, starts the GC - test edx, edx - jz short labConinue - // ; otherwise eax contains the collecting thread event - - // ; signal the collecting thread that it is stopped - push edx - push esi - call extern "$rt.SignalStopGCLA" - add esp, 4 - - // ; free lock - // ; could we use mov [esi], 0 instead? - mov edi, data : %CORE_GC_TABLE + gc_lock - mov ebx, 0FFFFFFFFh - lock xadd [edi], ebx - - // ; stop until GC is ended - call extern "$rt.WaitForSignalGCLA" - add esp, 4 - - // ; restore registers and try again - pop ecx - pop ebp - pop esi - - jmp labStart - -labConinue: - mov [data : %CORE_GC_TABLE + gc_signal], esi // set the collecting thread signal - mov ebp, esp - - // ; === thread synchronization === - - // ; create list of threads need to be stopped - mov eax, esi - // ; get tls entry address - mov esi, data : %CORE_THREAD_TABLE + tt_slots - mov edi, [esi - 4] -labNext: - mov edx, [esi] - test edx, edx - jz short labSkipTT - cmp eax, [edx + tt_sync_event] - setz cl - or ecx, [edx + tt_flags] - test ecx, 1 - // ; skip current thread signal / thread in safe region from wait list - jnz short labSkipSave - push [edx + tt_sync_event] -labSkipSave: - - // ; reset all signal events - push [edx + tt_sync_event] - call extern "$rt.SignalClearGCLA" - add esp, 4 - - lea esi, [esi + 8] - mov eax, [data : %CORE_GC_TABLE + gc_signal] -labSkipTT: - sub edi, 1 - jnz short labNext - - mov esi, data : %CORE_GC_TABLE + gc_lock - mov edx, 0FFFFFFFFh - mov ebx, ebp - - // ; free lock - // ; could we use mov [esi], 0 instead? - lock xadd [esi], edx - - mov ecx, esp - sub ebx, esp - jz short labSkipWait - - // ; wait until they all stopped - shr ebx, 2 - push ecx - push ebx - call extern "$rt.WaitForSignalsGCLA" - -labSkipWait: - // ; remove list - mov esp, ebp - - // ==== GCXT end ============== - - // ; create set of roots - mov ebp, esp - xor ecx, ecx - push ecx // ; reserve place - push ecx - push ecx - - // ; save static roots - mov ecx, [rdata : %SYSTEM_ENV] - mov esi, stat : %0 - shl ecx, 2 - push esi - push ecx - - // ; collect frames - mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] - mov ecx, eax - -labYGNextFrame: - mov esi, eax - mov eax, [esi] - test eax, eax - jnz short labYGNextFrame - - push ecx - sub ecx, esi - neg ecx - push ecx - - mov eax, [esi + 4] - test eax, eax - mov ecx, eax - jnz short labYGNextFrame - - mov [ebp-4], esp // ; save position for roots - - mov ebx, [ebp] - mov eax, esp - - // ; restore frame to correctly display a call stack - mov edx, ebp - mov ebp, [edx+4] - - // ; call GC routine push edx push ebx push eax - call extern "$rt.ForcedCollectGCLA" + call extern "$rt.CollectGCLA" - mov ebp, [esp+8] - add esp, 12 mov edi, eax + mov ebp, [esp+12] // ; GCXT: signal the collecting thread that GC is ended // ; should it be placed into critical section? @@ -507,6 +345,7 @@ labYGNextFrame: mov esp, ebp pop ecx + pop edx pop ebp pop esi ret @@ -841,6 +680,62 @@ inline %02Ch end +// ; peektls +inline %0BBh + + mov eax, [data : %CORE_TLS_INDEX] + mov ecx, fs: [2Ch] + mov eax, [ecx + eax * 4] + lea edi, [eax + __arg32_1] + mov ebx, [edi] + +end + +// ; storetls +inline %0BCh + + mov eax, [data : %CORE_TLS_INDEX] + mov ecx, fs: [2Ch] + mov eax, [ecx + eax * 4] + lea edi, [eax + __arg32_1] + mov [edi], ebx + +end + +// ; system minor collect +inline %1CFh + + mov edi, data : %CORE_GC_TABLE + gc_lock + +labWait: + mov edx, 1 + xor eax, eax + lock cmpxchg dword ptr[edi], edx + jnz short labWait + + xor ecx, ecx + xor edx, edx + call %GC_COLLECT + +end + +// ; system full collect +inline %2CFh + + mov edi, data : %CORE_GC_TABLE + gc_lock + +labWait: + mov edx, 1 + xor eax, eax + lock cmpxchg dword ptr[edi], edx + jnz short labWait + + xor ecx, ecx + mov edx, 1 + call %GC_COLLECT + +end + // ; system 3 (thread startup) inline %3CFh diff --git a/bin/elc60.cfg b/bin/elc60.cfg index d42762be3..d207a2a94 100644 --- a/bin/elc60.cfg +++ b/bin/elc60.cfg @@ -29,6 +29,7 @@ + KERNEL32 diff --git a/bin/templates/mt_win_console60.cfg b/bin/templates/mt_win_console60.cfg index f96593af8..6b3d04c9b 100644 --- a/bin/templates/mt_win_console60.cfg +++ b/bin/templates/mt_win_console60.cfg @@ -9,6 +9,10 @@ + + ..\amd64\corex60.bin + ..\amd64\corex60_win.bin + elenart60_64 @@ -20,7 +24,7 @@ - 10 + 1024 system'core_routines'mta_start diff --git a/build/aarch64/build_package_arm64.script b/build/aarch64/build_package_arm64.script index 2960e9061..844afff38 100755 --- a/build/aarch64/build_package_arm64.script +++ b/build/aarch64/build_package_arm64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.3.0.aarch64-linux +RELEASE=elena-6.3.1.aarch64-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ diff --git a/build/aarch64/control b/build/aarch64/control index 3da3ee69a..d4e15aeed 100644 --- a/build/aarch64/control +++ b/build/aarch64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.3.0 +Version: 6.3.1 Architecture: aarch64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/amd64/build_package_amd64.script b/build/amd64/build_package_amd64.script index 53564a43d..d16649752 100755 --- a/build/amd64/build_package_amd64.script +++ b/build/amd64/build_package_amd64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.3.0.amd64-linux +RELEASE=elena-6.3.1.amd64-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ diff --git a/build/amd64/control b/build/amd64/control index ebb52c770..54bad421f 100644 --- a/build/amd64/control +++ b/build/amd64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.3.0 +Version: 6.3.1 Architecture: amd64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/elena_inno.iss b/build/elena_inno.iss index a2b2b4b36..65370aa5e 100644 --- a/build/elena_inno.iss +++ b/build/elena_inno.iss @@ -7,7 +7,7 @@ ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{3CAA69D3-0F98-44B1-A73E-E864BA51D5BD} AppName=ELENA Programming Language -AppVersion=6.3.0 +AppVersion=6.3.1 ;AppVerName=ELENA Programming Language 6.2.0 AppPublisher=Alexey Rakov AppPublisherURL=http://github.com/ELENA-LANG/elena-lang @@ -18,7 +18,7 @@ DefaultGroupName=ELENA Programming Language AllowNoIcons=yes LicenseFile=..\doc\license InfoAfterFile=..\CHANGELOG.md -OutputBaseFilename=elena-lang-6.3.0.x86-win-setup +OutputBaseFilename=elena-lang-6.3.1.x86-win-setup Compression=lzma SolidCompression=yes ChangesEnvironment=yes diff --git a/build/i386/build_package_i386.script b/build/i386/build_package_i386.script index 1022969ac..efbf7b4b3 100755 --- a/build/i386/build_package_i386.script +++ b/build/i386/build_package_i386.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.3.0.i386-linux +RELEASE=elena-6.3.1.i386-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ diff --git a/build/i386/control b/build/i386/control index 25d579edf..dca2dbcdb 100644 --- a/build/i386/control +++ b/build/i386/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.3.0 +Version: 6.3.1 Architecture: i386 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/ppc64le/build_package_ppc64le.script b/build/ppc64le/build_package_ppc64le.script index 0a5715bb5..f117c3e66 100755 --- a/build/ppc64le/build_package_ppc64le.script +++ b/build/ppc64le/build_package_ppc64le.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.3.0.ppc64le-linux +RELEASE=elena-6.3.1.ppc64le-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ diff --git a/build/ppc64le/control b/build/ppc64le/control index 6c9aeed85..8bec1f661 100644 --- a/build/ppc64le/control +++ b/build/ppc64le/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.3.0 +Version: 6.3.1 Architecture: ppc64le Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/rebuild_data60_x64.bat b/build/rebuild_data60_x64.bat new file mode 100644 index 000000000..cbc329c44 --- /dev/null +++ b/build/rebuild_data60_x64.bat @@ -0,0 +1,53 @@ +REM NOTE : the script MUST be called from the root folder + +bin\sg64-cli dat\sg\syntax60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax60.dat bin + +bin\sg64-cli dat\sg\syntax50.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax50.dat bin + +bin\og64-cli dat\og\bc_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bc_rules60.dat bin + +bin\og64-cli -s dat\og\bt_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bt_rules60.dat bin + +@echo off +echo === Done === +@echo on + +@echo off +goto:eof +@echo on + +:Asm2BinError +echo ASM2BINX returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:CompilerError +echo ELC returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:TestError +echo System tests fail %ERRORLEVEL% +@echo off +goto:eof +@echo on diff --git a/build/rebuild_data60_x86.bat b/build/rebuild_data60_x86.bat new file mode 100644 index 000000000..961552a4b --- /dev/null +++ b/build/rebuild_data60_x86.bat @@ -0,0 +1,53 @@ +REM NOTE : the script MUST be called from the root folder + +.\bin\sg-cli dat\sg\syntax60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax60.dat bin + +.\bin\sg-cli dat\sg\syntax50.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax50.dat bin + +bin\og-cli dat\og\bc_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bc_rules60.dat bin + +bin\og-cli -s dat\og\bt_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bt_rules60.dat bin + +@echo off +echo === Done === +@echo on + +@echo off +goto:eof +@echo on + +:Asm2BinError +echo ASM2BINX returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:CompilerError +echo ELC returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:TestError +echo System tests fail %ERRORLEVEL% +@echo off +goto:eof +@echo on \ No newline at end of file diff --git a/build/rebuild_lib60_x64.bat b/build/rebuild_lib60_x64.bat index 873f16bf1..fe8ddd239 100644 --- a/build/rebuild_lib60_x64.bat +++ b/build/rebuild_lib60_x64.bat @@ -1,30 +1,21 @@ REM NOTE : the script MUST be called from the root folder -bin\sg64-cli dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -move dat\sg\syntax60.dat bin - -bin\og64-cli dat\og\bc_rules60.txt +bin\asm64-cli -amd64 asm\amd64\core60.asm bin\amd64 @echo off if %ERRORLEVEL% EQU -1 GOTO Asm2BinError @echo on -move dat\og\bc_rules60.dat bin -bin\og64-cli -s dat\og\bt_rules60.txt +bin\asm64-cli -amd64 asm\amd64\core60_win.asm bin\amd64 @echo off if %ERRORLEVEL% EQU -1 GOTO Asm2BinError @echo on -move dat\og\bt_rules60.dat bin -bin\asm64-cli -amd64 asm\amd64\core60.asm bin\amd64 +bin\asm64-cli -amd64 asm\amd64\corex60.asm bin\amd64 @echo off if %ERRORLEVEL% EQU -1 GOTO Asm2BinError @echo on -bin\asm64-cli -amd64 asm\amd64\core60_win.asm bin\amd64 +bin\asm64-cli -amd64 asm\amd64\corex60_win.asm bin\amd64 @echo off if %ERRORLEVEL% EQU -1 GOTO Asm2BinError @echo on diff --git a/build/rebuild_lib60_x86.bat b/build/rebuild_lib60_x86.bat index ee27a7b9b..07ca3284c 100644 --- a/build/rebuild_lib60_x86.bat +++ b/build/rebuild_lib60_x86.bat @@ -1,24 +1,5 @@ REM NOTE : the script MUST be called from the root folder -.\bin\sg-cli dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -move dat\sg\syntax60.dat bin - -bin\og-cli dat\og\bc_rules60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on -move dat\og\bc_rules60.dat bin - -bin\og-cli -s dat\og\bt_rules60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on -move dat\og\bt_rules60.dat bin - bin\asm-cli -x86 asm\x32\core60.asm bin\x32 @echo off if %ERRORLEVEL% EQU -1 GOTO Asm2BinError @@ -60,6 +41,7 @@ if %ERRORLEVEL% EQU -2 GOTO CompilerError @echo on bin\ldoc system doc\api +bin\ldoc system'collections'threadsafe doc\api bin\ldoc system'routines doc\api bin\ldoc system'runtime doc\api bin\ldoc system'threading doc\api diff --git a/dat/api2html/api2html.bat b/dat/api2html/api2html.bat index fe4be5ce3..3fb5e85f9 100644 --- a/dat/api2html/api2html.bat +++ b/dat/api2html/api2html.bat @@ -1,4 +1,5 @@ ..\..\bin\ldoc system +..\..\bin\ldoc system'collections'threadsafe ..\..\bin\ldoc system'routines ..\..\bin\ldoc system'routines'stex ..\..\bin\ldoc system'runtime diff --git a/dat/sg/syntax50.txt b/dat/sg/syntax50.txt new file mode 100644 index 000000000..073398cd4 --- /dev/null +++ b/dat/sg/syntax50.txt @@ -0,0 +1,936 @@ +__define eof 8195; +__define identifier 12292; +__define integer 12293; +__define string 12294; +__define hexinteger 12295; +__define reference 12296; +__defineterminal "}" 12297; +__define character 12298; +__define global 12299; +__define wide 12300; +__define constant 12301; +__define long 12302; +__define real 12303; + +__define DECLARATION 5120; +__define BLOCK 7184; +__define NO_BODY 7185; +__define TEMPLATE_BLOCK 4104; +__define PARAMETER 4106; +__define END_OF_BLOCK 4107; +__define DICTIONARY 4128; +__define META_STATEMENT 4129; +__define INCLUDE_STATEMENT 4130; +__define LOAD_STATEMENT 4131; +__define OBJECT 4145; +__define TEMPLATE_TYPE 4146; +__define ARRAY_TYPE 4147; +__define NESTED 4224; +__define CLOSURE 4225; +__define MESSAGE 4288; +__define OPERATOR 4310; +__define SUB_VARIABLE 4311; +__define RET_EXPRESSION 7220; +__define GET_EXPRESSION 7222; +__define INIT_EXPRESSION 7223; +__define ACCUM_EXPRESSION 7225; +__define NESTED_EXPRESSION 6197; +__define INDEXER_OPERATION 6209; +__define ASSIGN_OPERATION 6210; +__define ADDITION_ASSIGNMENT 6211; +__define ADD_OPERATION 6212; +__define SUB_OPERATION 6213; +__define LEN_OPERATION 6214; +__define IF_OPERATION 6215; +__define LESS_OPERATION 6216; +__define NAME_OPERATION 6217; +__define EQUAL_OPERATION 6218; +__define NOT_OPERATION 6219; +__define NOTEQUAL_OPERATION 6220; +__define LOOP_OPERATION 6221; +__define ELSE_OPERATION 6222; +__define IF_ELSE_OPERATION 6223; +__define MUL_OPERATION 6224; +__define DIV_OPERATION 6225; +__define NOTLESS_OPERATION 6226; +__define GREATER_OPERATION 6227; +__define NOTGREATER_OPERATION 6228; +__define EXTERN_OPERATION 6229; +__define NEGATE_OPERATION 6230; +__define VALUE_OPERATION 6231; +__define BAND_OPERATION 6232; +__define BOR_OPERATION 6233; +__define BXOR_OPERATION 6234; +__define BNOT_OPERATION 6235; +__define SHL_OPERATION 6236; +__define SHR_OPERATION 6237; +__define SUB_ASSIGNMENT 6238; +__define MUL_ASSIGNMENT 6239; +__define DIV_ASSIGNMENT 6240; +__define AND_OPERATION 6241; +__define OR_OPERATION 6242; +__define XOR_OPERATION 6243; +__define BREAK_OPERATION 6244; +__define LAZY_OPERATION 6245; +__define TUPLE_ASSIGNING 6246; +__define CONTINUE_OPERATION 6247; +__define YIELD_OPERATION 6248; +__define REFER_OPERATION 6251; +__define MESSAGE_OPERATION 6337; +__define PROPERTY_OPERATION 6340; +__define EXPRESSION 6288; +__define L5_EXPRESSION 6289; +__define SINGLE_EXPRESSION 6290; +__define L8_EXPRESSION 6291; +__define ROOT_EXPRESSION 6292; +__define L6_EXPRESSION 6293; +__define T_EXPRESSION 6294; +__define L4_EXPRESSION 6295; +__define NT_EXPRESSION 6296; +__define L7_EXPRESSION 6297; +__define L3_SINGLE_EXPRESSION 6298; +__define NESTED_ROOT_EXPRESSION 6299; +__define OPERATION_TEMPLATE 6300; +__define LT_EXPRESSION 6301; +__define SWITCH_OPTION 6353; +__define SWITCH_LAST_OPTION 6354; +__define SWITCH_CODE 6355; +__define COLLECTION_EXPRESSION 6356; +__define TUPLE_COLLECTION 6357; +__define POSTFIX 4201; +__define TEMPLATE_POSTFIX 4202; +__define TEMPLATE_ARG 4208; +__define DIMENSION 5233; +__define RESEND 7366; +__define CATCH_OPERATION 7367; +__define CATCH 7368; +__define FINAL_OPERATION 7386; +__define REDIRECT 7371; +__define ALT_OPERATION 7372; +__define ISNIL_OPERATION 7373; +__define SWITCH_OPERATION 7376; +__define COMPLEX_NAME 4302; +__define INLINE 4303; +__define SUB_DECLARATION 4312; +__define FINALLY 7385; +__define PARAMETER_BLOCK 4336; + +START ::= + { DECLARATION | META_DECLARATION }+ eof + | eof; + +META_DECLARATION ::= + "#new" DICTIONARY DECLARATION_END + | "#let" META_STATEMENT DECLARATION_END + | "#include" INCLUDE_STATEMENT DECLARATION_END + | "#load" LOAD_STATEMENT DECLARATION_END; + +DECLARATION ::= + { identifier | reference }+ IR_DECLARATION; + +IR_DECLARATION ::= + { TEMPLATE_BRACKETS identifier? | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ identifier } { POSTFIXES NESTED_SCOPE | SCOPE } + | { "," SUB_DECLARATION }+ { POSTFIXES NESTED_SCOPE | SCOPE } + | { "::" COMPLEX_NAME }+ TEMPLATE_BRACKETS? METHOD_SCOPE + | POSTFIXES NESTED_SCOPE + | SCOPE; + +SUB_DECLARATION ::= + { identifier | reference }+ { TEMPLATE_BRACKETS identifier? | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ identifier | eps }; + +DICTIONARY ::= + identifier+; + +META_STATEMENT ::= + EXPRESSION; + +LOAD_STATEMENT ::= + { reference | identifier }; + +INCLUDE_STATEMENT ::= + { identifier | reference }+ ^ OBJECT; + +NESTED_SCOPE ::= + "{" { DECLARATION | META_DECLARATION }* END_OF_BLOCK + | "=" GET_EXPRESSION DECLARATION_END + | DECLARATION_END; + +SCOPE ::= + "=" GET_EXPRESSION DECLARATION_END + | ":=" INIT_EXPRESSION DECLARATION_END + | "+=" ACCUM_EXPRESSION DECLARATION_END + | "{" { DECLARATION | META_DECLARATION }* END_OF_BLOCK + | "[" DIMENSION "]" DECLARATION_END + | METHOD_SCOPE + | DECLARATION_END; + +METHOD_SCOPE ::= + "(" { PARAMETER { "," PARAMETER }* }? ")" POSTFIXES? METHOD_BODY; + +POSTFIXES ::= + ":" POSTFIX { "," POSTFIX }*; + +METHOD_BODY ::= + "{" BLOCK + | "=" RET_EXPRESSION DECLARATION_END + | "<=" RESEND { DECLARATION_END | "{" BLOCK } + | "=>" REDIRECT DECLARATION_END + | NO_BODY; + +NO_BODY ::= + ";"; + +BLOCK ::= + STATEMENT NEXT_STATEMENT + | "^" RET_EXPRESSION LAST_STATEMENT + | END_OF_BLOCK; + +LAST_STATEMENT ::= + DECLARATION_END END_OF_BLOCK + | END_OF_BLOCK; + +NEXT_STATEMENT ::= + DECLARATION_END { + STATEMENT NEXT_STATEMENT + | "^" RET_EXPRESSION LAST_STATEMENT + | END_OF_BLOCK } + | END_OF_BLOCK; + +STATEMENT ::= + ROOT_EXPRESSION + | "#include" INCLUDE_STATEMENT + | "#let" META_STATEMENT + | "#new" DICTIONARY; + +RESEND ::= + identifier+ RESEND_R; + +REDIRECT ::= + EXPRESSION; + +RET_EXPRESSION ::= + EXPRESSION; + +INIT_EXPRESSION ::= + EXPRESSION; + +ACCUM_EXPRESSION ::= + EXPRESSION; + +GET_EXPRESSION ::= + EXPRESSION; + +T_EXPRESSION ::= + "{" BLOCK; + +T_EXPRESSION_F ::= + identifier { NT_EXPRESSION T_EXPRESSION_F | LT_EXPRESSION } + | eps; + +NT_EXPRESSION ::= + "{" BLOCK + | "::" NESTED_EXPRESSION ^NESTED + | "(" T_SUB_EXPRESSION; + +LT_EXPRESSION ::= + NESTED_ROOT_EXPRESSION ^ BLOCK; + +ROOT_EXPRESSION ::= + identifier { + { identifier }+ { + "," ^OBJECT SUB_VARIABLE { "," SUB_VARIABLE }* ASSIGN EXPRESSION ^TUPLE_ASSIGNING + | L0 ^OBJECT L0_R L1_OP? + | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { + identifier ^OBJECT ASSIGN ASSIGN_R + | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* + } + | ASSIGN ^OBJECT ASSIGN_R + | L2 ^OBJECT L2_R L3_OP* { L8_OP | L9_OP }? + | L3 ^OBJECT MESSAGE { + L3_R L3_OP* + | ASSIGN EXPRESSION ^PROPERTY_OPERATION + | eps ^PROPERTY_OPERATION } + | eps ^OBJECT } + | "," ^OBJECT SUB_VARIABLE { "," SUB_VARIABLE }* ASSIGN EXPRESSION ^TUPLE_ASSIGNING + | { reference | global } { + L3 ^OBJECT MESSAGE L3_R + | eps ^OBJECT } + | L0 ^OBJECT L0_R L0_OP* { + L1_OP + | L3 MESSAGE { + L3_R L3_OP* + | ASSIGN EXPRESSION ^PROPERTY_OPERATION + | eps ^PROPERTY_OPERATION } + | eps } + | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ identifier ^OBJECT ASSIGN ASSIGN_R + | ASSIGN ^OBJECT ASSIGN_R + | L1a_O_OP + | L2 ^OBJECT MESSAGE_PARAMETERS? ")" { + T_EXPRESSION T_EXPRESSION_F ^ TEMPLATE_BLOCK + | ISNIL ^MESSAGE_OPERATION SINGLE_EXPRESSION ^ISNIL_OPERATION + | LT_EXPRESSION ^ TEMPLATE_BLOCK + | TRY ^MESSAGE_OPERATION TRY_R + | L3 ^MESSAGE_OPERATION MESSAGE MESSAGE_R + | eps ^MESSAGE_OPERATION } + | L3 ^OBJECT { + OPERATOR MESSAGE? L3_R ^OPERATION_TEMPLATE + | MESSAGE { + L3_R { + L3 L3_F + | L4_OP + | L6_OP + | L9_OP + | eps } + | ASSIGN EXPRESSION ^PROPERTY_OPERATION + | L3 ^PROPERTY_OPERATION L3_F + | EQUAL ^PROPERTY_OPERATION L6_EXPRESSION ^EQUAL_OPERATION L8_OP? L9_OP? + | eps ^PROPERTY_OPERATION } + } + | L4_O_OP L4_OP* + | L5_O_OP + | LESS ^OBJECT TEMPLATE_ARG { "," TEMPLATE_ARG }* ">" ^TEMPLATE_TYPE + { + L3 ^OBJECT MESSAGE L3_R + | identifier ^OBJECT { ASSIGN ASSIGN_R }? } + | L7_O_OP + | L8_O_OP + | TRY ^OBJECT TRY_R + | FNL ^OBJECT FNL_R + | ALT ^OBJECT ALT_R + | T_EXPRESSION T_EXPRESSION_F ^ TEMPLATE_BLOCK + | "=>" ^OBJECT { SWITCH_OPTION+ SWITCH_LAST_OPTION? } ^SWITCH_OPERATION + | eps ^OBJECT } + | { reference | global } { + L3 ^OBJECT MESSAGE MESSAGE_R + | eps ^OBJECT } + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L0_OP* L3_OP* L4_OP* L5_OP* L6_OP? + | "!" EXPRESSION ^NOT_OPERATION + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION L3_OP* L4_OP* L5_OP* L6_OP? + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "(" SUB_EXPRESSION { + "=>" { SWITCH_OPTION+ SWITCH_LAST_OPTION? } ^SWITCH_OPERATION + | L2_OP L2_OP* L3_OP* + | L3_OP L3_OP* L7_OP* L8_OP? + | L7_OP L7_OP* L8_OP? + | L8_OP + | eps } + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION + | "$rep" EXPRESSION ^LOOP_OPERATION + | "$ext" EXPRESSION ^EXTERN_OPERATION + | "$break" ^BREAK_OPERATION + | "$continue" ^CONTINUE_OPERATION + | "$yield" EXPRESSION ^YIELD_OPERATION; + +NESTED_ROOT_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R L1_OP? + | ASSIGN ^OBJECT ASSIGN_R + | L2 ^OBJECT L2_R L3_OP* { L8_OP | L9_OP }? + | L3 ^OBJECT MESSAGE { + L3_R L3_OP* + | ASSIGN EXPRESSION ^PROPERTY_OPERATION + | eps ^PROPERTY_OPERATION } + | eps ^OBJECT } + | L0 ^OBJECT L0_R { + L1_OP + | L3_OP + | eps } + | ASSIGN ^OBJECT ASSIGN_R + | L1a_O_OP + | L2 ^OBJECT MESSAGE_PARAMETERS? ")" { + T_EXPRESSION T_EXPRESSION_F ^ TEMPLATE_BLOCK + | ISNIL ^MESSAGE_OPERATION SINGLE_EXPRESSION ^ISNIL_OPERATION + | eps ^MESSAGE_OPERATION } + | L3 ^OBJECT MESSAGE { + L3_R { + L3 L3_F + | L4_OP + | L6_OP + | L9_OP + | eps } + | ASSIGN EXPRESSION ^PROPERTY_OPERATION + | eps ^PROPERTY_OPERATION } + | L4_O_OP L4_OP* + | L5_O_OP + | L7_O_OP + | TRY ^OBJECT TRY_R + | T_EXPRESSION T_EXPRESSION_F ^ TEMPLATE_BLOCK + | "=>" ^OBJECT { SWITCH_OPTION+ SWITCH_LAST_OPTION? } ^SWITCH_OPERATION + | eps ^OBJECT } + | { reference | global } { + L3 ^OBJECT MESSAGE MESSAGE_R + | eps ^OBJECT } + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L4_OP* L5_OP* L6_OP? + | "!" EXPRESSION ^NOT_OPERATION + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION L3_OP* L4_OP* L5_OP* L6_OP? + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION + | "$rep" EXPRESSION ^LOOP_OPERATION + | "$ext" EXPRESSION ^EXTERN_OPERATION + | "$break" ^BREAK_OPERATION + | "$continue" ^CONTINUE_OPERATION; + +EXPRESSION ::= + identifier { + { identifier | reference }+ { + L0 ^OBJECT L0_R L1_OP? + | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { + L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? + | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* } + | ASSIGN ^OBJECT ASSIGN_R + | L2 ^OBJECT L2_R L3_OP* L5_OP* L6_OP? L7_OP* { L8_OP | L9_OP }? + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? + | LESS ^OBJECT TEMPLATE_ARG { "," TEMPLATE_ARG }* ">" ^TEMPLATE_TYPE { + L0 ^OBJECT L0_R + | L2 ^OBJECT L2_R L3_OP* + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* + | NESTED_EXPRESSION ^NESTED + } + | L6_O_OP_WM + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } + | L0 ^OBJECT L0_R L0_OP* { + L1_OP + | L3_OP L3_OP* L4_OP* L5_OP* + | L4_OP L4_OP* L5_OP* + | L5_OP + | L6_OP L7_OP* + | L7_OP + | L8_OP + | L9_OP + | eps } + | ASSIGN ^OBJECT ASSIGN_R + | L1a_O_OP + | L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? + | L3 ^OBJECT { MESSAGE MESSAGE_R | OPERATOR MESSAGE L3_R ^OPERATION_TEMPLATE } L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* { L8_OP | L9_OP }? + | L4_O_OP L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? + | L5_O_OP L5_OP* L6_OP? L7_OP* L9_OP? + | L6_O_OP L7_OP* L8_OP? + | L7_O_OP + | L8_O_OP + | ISNIL ^OBJECT SINGLE_EXPRESSION ^ISNIL_OPERATION + | TRY ^OBJECT TRY_R + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } + | { reference | global } { + L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? + | L3 ^OBJECT MESSAGE MESSAGE_R + | eps ^OBJECT } + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L0_OP* L3_OP* L4_OP* L5_OP* L6_OP? L9_OP* + | "(" SUB_EXPRESSION L2_OP? L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? + | "{" BLOCK ^CLOSURE + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION L3_OP* L4_OP* L5_OP* L6_OP? + | "!" EXPRESSION ^NOT_OPERATION + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION + | "$lazy" NESTED_SUB_EXPRESSION ^EXPRESSION ^LAZY_OPERATION; + +NESTED_SUB_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R L1_OP? + | ASSIGN ^OBJECT ASSIGN_R + | L2 ^OBJECT L2_R L3_OP* { L8_OP | L9_OP }? + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } + | L0 ^OBJECT L0_R + | ASSIGN ^OBJECT ASSIGN_R + | L2 ^OBJECT L2_R L9_OP? + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* L6_OP? L9_OP? + | L4_O_OP + | L5_O_OP + | eps ^OBJECT } + | { reference | global } ^OBJECT + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L0_OP* L4_OP* L5_OP* L6_OP?; + +SUB_EXPRESSION ::= + identifier { + identifier+ { + L2 ^OBJECT L2_R L3_OP* L5_OP* { L8_OP | L9_OP }? ")" + | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { + L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? + | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* } ")" + | "," ^ PARAMETER PARAMETER { "," PARAMETER }* { + "=>" RET_EXPRESSION ^CLOSURE ")" ^EXPRESSION + | ")" "{" BLOCK ^CLOSURE ^EXPRESSION } + | ")" { + "{" ^ PARAMETER BLOCK ^CLOSURE ^EXPRESSION + | eps ^OBJECT ^EXPRESSION } + } + | L0 ^OBJECT L0_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* ")" + | L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? ")" + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? ")" + | L4_O_OP L4_OP* L5_OP* L6_OP? L7_OP* ")" + | L5_O_OP L5_OP* L6_OP? L7_OP* ")" + | L6_O_OP L7_OP* ")" + | L7_O_OP ")" + | L9_O_OP ")" + | "=>" ^ PARAMETER RET_EXPRESSION ^CLOSURE ")" ^EXPRESSION + | "," ^ OBJECT ^ EXPRESSION EXPRESSION { "," EXPRESSION }* + { "=>" ^ PARAMETER_BLOCK RET_EXPRESSION ^CLOSURE ")" ^EXPRESSION + | ")" ^ PARAMETER_BLOCK "{" BLOCK ^CLOSURE ^EXPRESSION } + | ")" { + "{" ^ PARAMETER BLOCK ^CLOSURE ^EXPRESSION + | eps ^OBJECT ^EXPRESSION } + } + | { reference | global } { + L3 ^OBJECT MESSAGE MESSAGE_R ")" + | ")" ^OBJECT } + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L4_OP* L5_OP* L6_OP? L7_OP* { + "," ^EXPRESSION EXPRESSION { "," EXPRESSION }* ^ TUPLE_COLLECTION + | eps + } ")" ^EXPRESSION + + | "(" SUB_EXPRESSION L2_OP? L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? ")" + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION ")" ^EXPRESSION + | "!" EXPRESSION ^NOT_OPERATION ")" ^EXPRESSION + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION ^EXPRESSION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION; + +T_SUB_EXPRESSION ::= + identifier+ { + "," ^ PARAMETER PARAMETER { "," PARAMETER }* { + ")" "{" BLOCK ^CLOSURE ^EXPRESSION } + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L9_OP? ")" ^EXPRESSION + | L6_O_OP ")" ^EXPRESSION + | ")" { + "{" ^ PARAMETER BLOCK ^CLOSURE ^EXPRESSION + | eps ^OBJECT ^EXPRESSION + } + }; + +SUB_SINGLE_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R L1_OP? + | ASSIGN ^OBJECT ASSIGN_R + | L2 ^OBJECT L2_R L3_OP* { L8_OP | L9_OP }? + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } ")" + | L0 ^OBJECT L0_R ")" + | ASSIGN ^OBJECT ASSIGN_R ")" + | L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L9_OP? ")" + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* L6_OP? L9_OP? ")" + | L4_O_OP ")" + | L5_O_OP ")" + | ")" ^OBJECT } + | { reference | global } ^OBJECT ")" + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L4_OP* L5_OP* L6_OP? ")"; + +SUB_L3_SINGLE_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R ")" + | L2 ^OBJECT L2_R L3_OP* ")" + | NESTED_EXPRESSION ^NESTED L3_OP* ")" + | LESS TEMPLATE_ARG { "," TEMPLATE_ARG }* ">" ^TEMPLATE_TYPE { + L0 ^OBJECT L0_R ")" + | L2 ^OBJECT L2_R L3_OP* ")" + | NESTED_EXPRESSION ^NESTED ")" + | identifier ")" "{" ^ PARAMETER BLOCK ^CLOSURE + } + | "," ^ PARAMETER PARAMETER { "," PARAMETER }* { + "=>" RET_EXPRESSION ^CLOSURE ")" ^EXPRESSION + | ")" "{" BLOCK ^CLOSURE ^EXPRESSION + } + | "=>" ^ PARAMETER RET_EXPRESSION ^CLOSURE ")" ^EXPRESSION + | ")" { + "{" ^ PARAMETER BLOCK ^CLOSURE + | eps ^OBJECT } + } + | L0 ^OBJECT L0_R ")" + | L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L9_OP? ")" + | L3 ^OBJECT MESSAGE MESSAGE_R ")" + | L4_O_OP L4_OP* ")" + | L5_O_OP ")" + | "=>" ^ PARAMETER RET_EXPRESSION ^CLOSURE ")" ^EXPRESSION + | "," ^ PARAMETER PARAMETER { "," PARAMETER }* { + "=>" RET_EXPRESSION ^CLOSURE ")" ^EXPRESSION + | ")" "{" BLOCK ^CLOSURE ^EXPRESSION } + | ")" { + "{" ^ PARAMETER BLOCK ^CLOSURE + | eps ^OBJECT } + } + | { reference | global } ^OBJECT ")" + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT ")" + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION ")" + | "!" EXPRESSION ^NOT_OPERATION ")" + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION ")" + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION ")" + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION ")" + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION ")"; + +SINGLE_EXPRESSION ::= + { identifier | reference | global }+ ^OBJECT + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT + | "(" SUB_SINGLE_EXPRESSION; + +L4_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R + | L2 ^OBJECT L2_R L3_OP* + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } + | L0 ^OBJECT L0_R + | L2 ^OBJECT L2_R + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* + | eps ^OBJECT } + | { reference | global } ^OBJECT + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L3_OP* + | "(" SUB_EXPRESSION L3_OP* + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION L3_OP* + | "!" L4_EXPRESSION ^NOT_OPERATION + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION; + +L5_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R + | L2 ^OBJECT L2_R L3_OP* + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } + | L0 ^OBJECT L0_R L0_OP* L3_OP* + | L2 ^OBJECT L2_R + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP*L4_OP* + | L4_O_OP L4_OP* + | eps ^OBJECT } + | { reference | global } ^OBJECT + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L4_OP* + | "(" SUB_EXPRESSION L3_OP* L4_OP* + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION L3_OP* L4_OP* + | "!" L5_EXPRESSION ^NOT_OPERATION + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION; + +L3_F ::= + MESSAGE { + L3_R { + L3 L3_F + | eps } + | ASSIGN EXPRESSION ^PROPERTY_OPERATION + | L3 ^PROPERTY_OPERATION L3_F + | eps ^PROPERTY_OPERATION + }; + +L3_SINGLE_EXPRESSION ::= + identifier ^OBJECT + | { reference | global } ^OBJECT + | { string | integer | hexinteger | character | constant | long | real } ^OBJECT + | "(" SUB_L3_SINGLE_EXPRESSION; + +L6_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R + | L2 ^OBJECT L2_R L3_OP* + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } + | L0 ^OBJECT L0_R L3_OP* L4_OP* L5_OP* + | L2 ^OBJECT L2_R + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* + | L4_O_OP L4_OP* L5_OP* + | L5_O_OP + | eps ^OBJECT } + | { reference | global } ^OBJECT + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L3_OP* L4_OP* L5_OP* + | "(" SUB_EXPRESSION L2_OP? L3_OP* L4_OP* L5_OP* + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION L3_OP* L4_OP* L5_OP* + | "!" L6_EXPRESSION ^NOT_OPERATION + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION; + +L7_EXPRESSION ::= + identifier { + { identifier }+ { + L0 ^OBJECT L0_R + | L2 ^OBJECT L2_R L3_OP* + | NESTED_EXPRESSION ^NESTED L3_OP* + | eps ^OBJECT } + | L0 ^OBJECT L0_R L3_OP* L4_OP* L5_OP* L6_OP? + | L2 ^OBJECT L2_R L3_OP* L4_OP* L5_OP* L6_OP? + | L3 ^OBJECT MESSAGE MESSAGE_R L3_OP* L4_OP* L5_OP* L6_OP? + | L4_O_OP L4_OP* L5_OP* L6_OP? + | L5_O_OP L6_OP? + | L6_O_OP + | eps ^OBJECT } + | { reference | global } ^OBJECT + | { string | integer | hexinteger | long | real | constant | character | wide } ^OBJECT L4_OP* L5_OP* L6_OP? + | "(" SUB_EXPRESSION L2_OP? L3_OP* L4_OP* L5_OP* L6_OP? + | "*" SINGLE_EXPRESSION ^VALUE_OPERATION + | "!" L7_EXPRESSION ^NOT_OPERATION + | "~" SINGLE_EXPRESSION ^BNOT_OPERATION + | "-" SINGLE_EXPRESSION ^NEGATE_OPERATION + | "$name" SINGLE_EXPRESSION ^NAME_OPERATION + | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION + | "$len" SINGLE_EXPRESSION ^LEN_OPERATION; + +L8_EXPRESSION ::= + "{" BLOCK ^ CLOSURE + | SINGLE_EXPRESSION; + +MESSAGE_PARAMETER ::= + EXPRESSION; + +L0 ::= "["; +ASSIGN ::= ":="; +L2 ::= "("; +L3 ::= "."; +BAND ::= "&"; +BOR ::= "|"; +BXOR ::= "^"; +STAR ::= "*"; +DIV ::= "/"; +SHL ::= "$shl"; +SHR ::= "$shr"; +APPEND ::= "+="; +REDUCE ::= "-="; +AMUL ::= "*="; +ADIV ::= "/="; +PLUS ::= "+"; +MINUS ::= "-"; +EQUAL ::= "=="; +NOTEQUAL ::= "!="; +LESS ::= "<"; +NOTLESS ::= ">="; +NOTGREATER ::= "<="; +GREATER ::= ">"; +AND ::= "&&"; +OR ::= "||"; +XOR ::= "^^"; +IF ::= "?"; +ELSE ::= "!"; +TRY ::= "\\"; +ALT ::= "\"; +ISNIL ::= "??"; +FNL ::= "$fnl"; + +L0_R ::= + EXPRESSION "]" ^INDEXER_OPERATION; + +L0_OP ::= + L0 L0_R; + +ASSIGN_R ::= + EXPRESSION ^ASSIGN_OPERATION; + +L1_OP ::= + ASSIGN ASSIGN_R; + +L1a_O_OP ::= + APPEND ^OBJECT EXPRESSION ^ADDITION_ASSIGNMENT + | REDUCE ^OBJECT EXPRESSION ^SUB_ASSIGNMENT + | AMUL ^OBJECT EXPRESSION ^MUL_ASSIGNMENT + | ADIV ^OBJECT EXPRESSION ^DIV_ASSIGNMENT; + +L2_R ::= + MESSAGE_PARAMETER { "," MESSAGE_PARAMETER }* ")" ^MESSAGE_OPERATION + | ")" ^MESSAGE_OPERATION; + +L2_OP ::= + L2 L2_R; + +L3_R ::= + "(" MESSAGE_PARAMETERS? ")" ^ MESSAGE_OPERATION + | ":" L3_SINGLE_EXPRESSION ^ MESSAGE_OPERATION; + +MESSAGE_R ::= + L3_R + | eps ^PROPERTY_OPERATION; + +RESEND_R ::= + "(" MESSAGE_PARAMETERS? ")" ^ MESSAGE_OPERATION + | eps ^PROPERTY_OPERATION; + +L3_OP ::= + L3 MESSAGE MESSAGE_R; + +L4_OP ::= + BAND L4_EXPRESSION ^BAND_OPERATION + | BOR L4_EXPRESSION ^BOR_OPERATION + | BXOR L4_EXPRESSION ^BXOR_OPERATION + | STAR L4_EXPRESSION ^MUL_OPERATION + | DIV L4_EXPRESSION ^DIV_OPERATION + | SHL L4_EXPRESSION ^SHL_OPERATION + | SHR L4_EXPRESSION ^SHR_OPERATION; + +L4_O_OP ::= + BAND ^OBJECT L4_EXPRESSION ^BAND_OPERATION + | BOR ^OBJECT L4_EXPRESSION ^BOR_OPERATION + | BXOR ^OBJECT L4_EXPRESSION ^BXOR_OPERATION + | STAR ^OBJECT L4_EXPRESSION ^MUL_OPERATION + | DIV ^OBJECT L4_EXPRESSION ^DIV_OPERATION + | SHL ^OBJECT L4_EXPRESSION ^SHL_OPERATION + | SHR ^OBJECT L4_EXPRESSION ^SHR_OPERATION; + +L5_OP ::= + MINUS L5_EXPRESSION ^SUB_OPERATION + | PLUS L5_EXPRESSION ^ADD_OPERATION; + +L5_O_OP ::= + MINUS ^OBJECT L5_EXPRESSION ^SUB_OPERATION + | PLUS ^OBJECT L5_EXPRESSION ^ADD_OPERATION; + +L6_OP ::= + EQUAL L6_EXPRESSION ^EQUAL_OPERATION + | NOTEQUAL L6_EXPRESSION ^NOTEQUAL_OPERATION + | NOTLESS L6_EXPRESSION ^NOTLESS_OPERATION + | GREATER L6_EXPRESSION ^GREATER_OPERATION + | NOTGREATER L6_EXPRESSION ^NOTGREATER_OPERATION + | LESS L6_EXPRESSION ^LESS_OPERATION; + +L6_O_OP ::= + EQUAL ^OBJECT L6_EXPRESSION ^EQUAL_OPERATION + | NOTEQUAL ^OBJECT L6_EXPRESSION ^NOTEQUAL_OPERATION + | NOTLESS ^OBJECT L6_EXPRESSION ^NOTLESS_OPERATION + | GREATER ^OBJECT L6_EXPRESSION ^GREATER_OPERATION + | NOTGREATER ^OBJECT L6_EXPRESSION ^NOTGREATER_OPERATION + | LESS ^OBJECT L6_EXPRESSION ^LESS_OPERATION; + +L6_O_OP_WM ::= + EQUAL ^OBJECT L6_EXPRESSION ^EQUAL_OPERATION + | NOTEQUAL ^OBJECT L6_EXPRESSION ^NOTEQUAL_OPERATION + | NOTLESS ^OBJECT L6_EXPRESSION ^NOTLESS_OPERATION + | GREATER ^OBJECT L6_EXPRESSION ^GREATER_OPERATION + | NOTGREATER ^OBJECT L6_EXPRESSION ^NOTGREATER_OPERATION; + +L7_OP ::= + AND L7_EXPRESSION ^AND_OPERATION + | OR L7_EXPRESSION ^OR_OPERATION + | XOR L7_EXPRESSION ^OR_OPERATION; + +L7_O_OP ::= + AND ^OBJECT L7_EXPRESSION ^AND_OPERATION + | OR ^OBJECT L7_EXPRESSION ^OR_OPERATION + | XOR ^OBJECT L7_EXPRESSION ^OR_OPERATION; + +IF_R ::= + L8_EXPRESSION { eps ^IF_OPERATION | ":" L8_EXPRESSION ^IF_ELSE_OPERATION }; + +ELSE_R ::= + L8_EXPRESSION ^ELSE_OPERATION; + +L8_OP ::= + IF IF_R + | ELSE ELSE_R; + +L8_O_OP ::= + IF ^OBJECT IF_R + | ELSE ^OBJECT ELSE_R; + +TRY_R ::= + CATCH { "$fnl" FINALLY }? ^CATCH_OPERATION; + +FNL_R ::= + FINALLY ^FINAL_OPERATION; + +ALT_R ::= + CATCH ^ALT_OPERATION; + +CATCH ::= + MESSAGE MESSAGE_R; + +FINALLY ::= + L7_EXPRESSION; + +L9_O_OP ::= + TRY ^OBJECT TRY_R + | ALT ^OBJECT ALT_R + | ISNIL ^OBJECT SINGLE_EXPRESSION ^ISNIL_OPERATION; + +L9_OP ::= + TRY TRY_R + | ALT ALT_R + | ISNIL SINGLE_EXPRESSION ^ISNIL_OPERATION; + +NESTED_EXPRESSION ::= + "{" { DECLARATION | META_DECLARATION }* END_OF_BLOCK; + +MESSAGE_PARAMETERS ::= + MESSAGE_PARAMETER { "," MESSAGE_PARAMETER }*; + +TEMPLATE_BRACKETS ::= + "<" TEMPLATE_ARG { "," TEMPLATE_ARG }* ">"; + +TEMPLATE_ARG ::= + identifier { TEMPLATE_BRACKETS ^ TEMPLATE_TYPE }? + | reference + | global; + +PARAMETER ::= + identifier+ { + DYNAMIC_DIMENSION ^ARRAY_TYPE identifier + | TEMPLATE_BRACKETS identifier + | eps }; + +SUB_VARIABLE ::= + identifier+ { + DYNAMIC_DIMENSION ^ARRAY_TYPE identifier + | TEMPLATE_BRACKETS identifier + | eps }; + +MESSAGE ::= + identifier; + +OPERATOR ::= + "\" ^ ALT_OPERATION | "?" ^ IF_OPERATION | "!" ^ ELSE_OPERATION; + +SWITCH_OPTION ::= + identifier ^ OBJECT SWITCH_CODE + | { integer | character | string } ^ OBJECT SWITCH_CODE; + +SWITCH_LAST_OPTION ::= + ":" SWITCH_CODE; + +SWITCH_CODE ::= + "{" BLOCK; + +COLLECTION ::= + EXPRESSION { "," EXPRESSION }* ; + +POSTFIX ::= + identifier { + TEMPLATE_BRACKETS ^ TEMPLATE_TYPE + | "(" MESSAGE_PARAMETER { "," MESSAGE_PARAMETER }* ")" ^ INLINE + | eps }; + +DIMENSION ::= + integer + | hexinteger + | identifier; + +COMPLEX_NAME ::= + identifier; + +DYNAMIC_DIMENSION ::= + "[]"; + +DECLARATION_END ::= + ";"; + +END_OF_BLOCK ::= + "}"; diff --git a/dat/sg/syntax60.txt b/dat/sg/syntax60.txt index a4df34ce0..4ccb2f0ab 100644 --- a/dat/sg/syntax60.txt +++ b/dat/sg/syntax60.txt @@ -400,7 +400,7 @@ NESTED_ROOT_EXPRESSION ::= | TRY ^MESSAGE_OPERATION TRY_R | FNL ^MESSAGE_OPERATION FNL_R | ALT ^MESSAGE_OPERATION ALT_R - | ISNIL ^MESSAGE_OPERATION SINGLE_EXPRESSION ^ISNIL_OPERATION + | ISNIL ^MESSAGE_OPERATION EXPRESSION ^ISNIL_OPERATION | T_EXPRESSION T_EXPRESSION_F ^ TEMPLATE_BLOCK | eps ^MESSAGE_OPERATION } @@ -450,7 +450,7 @@ EXPRESSION ::= | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? } | ":" ^OBJECT ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK - | "=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION + | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_F | ASSIGN ^OBJECT ASSIGN_R | L1a_OOP @@ -497,7 +497,7 @@ EXPRESSION ::= | identifier ^OBJECT { ASSIGN ASSIGN_R }? } | ":" ^OBJECT ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK - | "=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION + | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_F | L1a_OOP | ASSIGN ^OBJECT ASSIGN_R @@ -820,7 +820,7 @@ L4_EXPRESSION ::= | "{" NESTED_EXPRESSION ^NESTED L2_OP* L3_OP* | eps ^OBJECT } - | "=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION + | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_OP* L2_OP* L3_OP* | L2_OOP L2_OP* L3_OP* | L3_OOP L3_OP* @@ -853,7 +853,7 @@ L5_EXPRESSION ::= | "{" NESTED_EXPRESSION ^NESTED L2_OP* L3_OP* L4_OP* | eps ^OBJECT } - | "=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION + | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_OP* L2_OP* L3_OP* L4_OP* | L2_OOP L2_OP* L3_OP* L4_OP* | L3_OOP L3_OP* L4_OP* @@ -888,7 +888,7 @@ L6_EXPRESSION ::= | "{" NESTED_EXPRESSION ^NESTED L2_OP* L3_OP* L4_OP* L5_OP* | eps ^OBJECT } - | "=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION + | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_OP* L2_OP* L3_OP* L4_OP* L5_OP* | L2_OOP L2_OP* L3_OP* L4_OP* L5_OP* | L3_OOP L3_OP* L4_OP* L5_OP* @@ -925,7 +925,7 @@ L7_EXPRESSION ::= | "{" NESTED_EXPRESSION ^NESTED L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? | eps ^OBJECT } - | "=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION + | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_OP* L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? | L2_OOP L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? | L3_OOP L3_OP* L4_OP* L5_OP* L6_OP? @@ -998,7 +998,7 @@ RI_F ::= | TRY ^MESSAGE_OPERATION TRY_R | FNL ^MESSAGE_OPERATION FNL_R | ALT ^MESSAGE_OPERATION ALT_R - | ISNIL ^MESSAGE_OPERATION SINGLE_EXPRESSION ^ISNIL_OPERATION; + | ISNIL ^MESSAGE_OPERATION EXPRESSION ^ISNIL_OPERATION; L_F ::= L0_OP+ L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? @@ -1100,7 +1100,7 @@ L3_F ::= | TRY ^PROPERTY_OPERATION TRY_R | ALT ^PROPERTY_OPERATION ALT_R | FNL ^PROPERTY_OPERATION FNL_R - | ISNIL ^PROPERTY_OPERATION SINGLE_EXPRESSION ^ISNIL_OPERATION; + | ISNIL ^PROPERTY_OPERATION EXPRESSION ^ISNIL_OPERATION; L0_OP ::= SBRACKET INDEXER_R; @@ -1195,13 +1195,13 @@ L9_OP ::= TRY TRY_R | FNL FNL_R | ALT ALT_R - | ISNIL SINGLE_EXPRESSION ^ISNIL_OPERATION; + | ISNIL EXPRESSION ^ISNIL_OPERATION; L9_OOP ::= TRY ^OBJECT TRY_R | FNL ^OBJECT FNL_R | ALT ^OBJECT ALT_R - | ISNIL ^OBJECT SINGLE_EXPRESSION ^ISNIL_OPERATION; + | ISNIL ^OBJECT EXPRESSION ^ISNIL_OPERATION; INDEXER_R ::= EXPRESSION "]" ^INDEXER_OPERATION; diff --git a/doc/api/algorithms-summary.html b/doc/api/algorithms-summary.html index ff7e8acc5..eb674cc47 100644 --- a/doc/api/algorithms-summary.html +++ b/doc/api/algorithms-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module algorithms +ELENA Standard Library 6.3: Module algorithms @@ -19,7 +19,7 @@
-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
@@ -104,7 +104,7 @@

-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
diff --git a/doc/api/algorithms.html b/doc/api/algorithms.html index a6d4b7c11..bcead67cc 100644 --- a/doc/api/algorithms.html +++ b/doc/api/algorithms.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module algorithms +ELENA Standard Library 6.3: Module algorithms @@ -19,7 +19,7 @@
-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
@@ -227,7 +227,7 @@

Extension Summary

-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
diff --git a/doc/api/cellular-summary.html b/doc/api/cellular-summary.html index 088498fc5..13ac71be0 100644 --- a/doc/api/cellular-summary.html +++ b/doc/api/cellular-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module cellular +ELENA Standard Library 6.3: Module cellular @@ -19,7 +19,7 @@
-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
@@ -102,7 +102,7 @@

-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
diff --git a/doc/api/cellular.html b/doc/api/cellular.html index e4360dbaf..970293544 100644 --- a/doc/api/cellular.html +++ b/doc/api/cellular.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module cellular +ELENA Standard Library 6.3: Module cellular @@ -19,7 +19,7 @@
-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
@@ -496,7 +496,7 @@

Method Summary

-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
diff --git a/doc/api/extensions-dynamic-summary.html b/doc/api/extensions-dynamic-summary.html index 2488cdee7..e2ba67a16 100644 --- a/doc/api/extensions-dynamic-summary.html +++ b/doc/api/extensions-dynamic-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'dynamic +ELENA Standard Library 6.3: Module extensions'dynamic @@ -19,7 +19,7 @@
-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
@@ -77,7 +77,7 @@

-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
diff --git a/doc/api/extensions-dynamic.html b/doc/api/extensions-dynamic.html index 288c240f7..39334b930 100644 --- a/doc/api/extensions-dynamic.html +++ b/doc/api/extensions-dynamic.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'dynamic +ELENA Standard Library 6.3: Module extensions'dynamic @@ -19,7 +19,7 @@
-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
@@ -82,7 +82,7 @@

Extension Summary

-ELENA Standard Library
6.0 +ELENA Standard Library
6.3
diff --git a/doc/api/extensions-io-summary.html b/doc/api/extensions-io-summary.html index dbb90a8d8..690d885e5 100644 --- a/doc/api/extensions-io-summary.html +++ b/doc/api/extensions-io-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'io +ELENA Standard Library 4.1: Module extensions'io @@ -19,7 +19,7 @@
-ELENA Standard Library
6.0 +ELENA Standard Library
4.1
@@ -36,37 +36,19 @@

  • -Class Summary +Extended Class Summary
    - + - - - - - - - -
    Class nameExtended class name Description
    -BufferWriter +Object
    -public class BufferWriter
    -
    -ByteArrayReader - -
    -public class ByteArrayReader
    -
    -ByteArrayWriter - -
    -public class ByteArrayWriter
    +Object
    @@ -84,7 +66,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    4.1
    diff --git a/doc/api/extensions-io.html b/doc/api/extensions-io.html index d59110f13..d2d95693d 100644 --- a/doc/api/extensions-io.html +++ b/doc/api/extensions-io.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'io +ELENA Standard Library 4.1: Module extensions'io @@ -19,136 +19,30 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    4.1
    - + - +
    -extensions'io'
    -

    BufferWriter

    +system'
    +

    Object



    -public class BufferWriter
    +Object
    - - -
      -
    • -

      Field Summary

      - - - - - - - - - - - - - -
      Modifier and TypeField
      - -IntNumber -_position -
      - - -_buffer -
      -
    • -
    - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -internal   -flush(BufferWriter bufferWriter, BinaryWriter externalWriter) - -
      -
    • -
    - +
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  Object -Source() -
      -
    • -
    - - - + -
    -
    - - - -
    -
    -extensions'io'
    -

    ByteArrayReader

    -
    -
    -
    -
    -
    -
    -public class ByteArrayReader
    -
    -
    - - - - - - -
      -
    • -

      Property Summary

      - - - - - - - - - - - - - -
      Modifier and TypeProperty
      - -get  Object -Source() -
      - -get  BoolValue -Available() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - - -read(system'ByteNumber[] array, ref IntNumber actualLength) - -
      - - -close() - -
    -
    -
    - - - -
    -
    -extensions'io'
    -

    ByteArrayWriter

    -
    -
    -
    -
    -
    -public class ByteArrayWriter
    -
    -
    - - - - - - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  Object -Source() -
      -
    • -
    - -
    @@ -494,7 +88,7 @@

    Method Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    4.1
    diff --git a/doc/api/extensions-routines-summary.html b/doc/api/extensions-routines-summary.html index 65998a249..860f3ded3 100644 --- a/doc/api/extensions-routines-summary.html +++ b/doc/api/extensions-routines-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'routines +ELENA Standard Library 6.3: Module extensions'routines @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -176,7 +176,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/extensions-routines.html b/doc/api/extensions-routines.html index 35cdd48d9..b0e75619f 100644 --- a/doc/api/extensions-routines.html +++ b/doc/api/extensions-routines.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'routines +ELENA Standard Library 6.3: Module extensions'routines @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -1147,7 +1147,7 @@

    Extension Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/extensions-scripting-summary.html b/doc/api/extensions-scripting-summary.html index d027cb107..40ca57b10 100644 --- a/doc/api/extensions-scripting-summary.html +++ b/doc/api/extensions-scripting-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'scripting +ELENA Standard Library 6.3: Module extensions'scripting @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -84,7 +84,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/extensions-scripting.html b/doc/api/extensions-scripting.html index dd029bb13..5c2268bc8 100644 --- a/doc/api/extensions-scripting.html +++ b/doc/api/extensions-scripting.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module extensions'scripting +ELENA Standard Library 6.3: Module extensions'scripting @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -358,7 +358,7 @@

    Constructor / Static Method Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/extensions-summary.html b/doc/api/extensions-summary.html index 8fdba95b7..e30b2c668 100644 --- a/doc/api/extensions-summary.html +++ b/doc/api/extensions-summary.html @@ -217,15 +217,6 @@

    public class Object - - -String - - -
    -public class String
    - -

  • diff --git a/doc/api/extensions.html b/doc/api/extensions.html index 57513098f..7788ecd6c 100644 --- a/doc/api/extensions.html +++ b/doc/api/extensions.html @@ -780,9 +780,9 @@

    Constructor / Static Method Summary

    -internal  RandomGenerator +RandomGenerator
    -constructor() +xtensions$$#constructor() @@ -1384,24 +1384,6 @@

    Extension Summary

    -printWide(params Object[] list) - - - - - - - - -printWideLine(params Object[] list) - - - - - - - - dispatch() @@ -1537,54 +1519,6 @@

    Extension Summary


    - - - -
    -
    -system'
    -

    String

    -
    -
    -
    -
    -
    -
    -public class String
    -
    -
    - -
      -
    • -

      Extension Summary

      - - - - - - - - - - - - - -
      Modifier and TypeExtension Method
      - - -dispatch() - -
      - - -interpolate(params Object[] args) - -
      -
    • -
    -
    -
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -273,7 +273,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/forms.html b/doc/api/forms.html index 7c84c8a4c..2e6a3980d 100644 --- a/doc/api/forms.html +++ b/doc/api/forms.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module forms +ELENA Standard Library 6.3: Module forms @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -4544,7 +4544,7 @@

    Method Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/index.html b/doc/api/index.html index 326875fe0..9ba1bede3 100644 --- a/doc/api/index.html +++ b/doc/api/index.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.2 +ELENA Standard Library 6.0 @@ -19,17 +19,17 @@
    -ELENA Standard Library
    6.2 +ELENA Standard Library
    6.0

    -ELENA Object Library 6.2 +ELENA Object Library 6.0

    -
    This document is the API specification for the ELENA Object Library, version 6.2.
    +
    This document is the API specification for the ELENA Object Library, version 6.0.
    @@ -557,7 +599,7 @@

    -ELENA Standard Library
    6.2 +ELENA Standard Library
    6.0

    diff --git a/doc/api/ltests-summary.html b/doc/api/ltests-summary.html index bad8cfce3..3292f9ea6 100644 --- a/doc/api/ltests-summary.html +++ b/doc/api/ltests-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module ltests +ELENA Standard Library 6.3: Module ltests @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -66,7 +66,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/ltests.html b/doc/api/ltests.html index dd2f7a3c5..91fd5ccd3 100644 --- a/doc/api/ltests.html +++ b/doc/api/ltests.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module ltests +ELENA Standard Library 6.3: Module ltests @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -83,7 +83,7 @@

    Method Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/net-summary.html b/doc/api/net-summary.html index 1bb3280e2..5f40ca9eb 100644 --- a/doc/api/net-summary.html +++ b/doc/api/net-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module net +ELENA Standard Library 6.3: Module net @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -111,7 +111,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/net.html b/doc/api/net.html index 596e77957..c973472e2 100644 --- a/doc/api/net.html +++ b/doc/api/net.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module net +ELENA Standard Library 6.3: Module net @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -879,7 +879,7 @@

    Method Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-collections-summary.html b/doc/api/system-collections-summary.html index ebca025be..b3f729b7f 100644 --- a/doc/api/system-collections-summary.html +++ b/doc/api/system-collections-summary.html @@ -116,51 +116,6 @@

    -SortedArrayList - - -
    -public class SortedArrayList
    - - - - -SortedList - - -
    -public class SortedList
    - - - - -SortedList<T1,T2> - - -
    -public template SortedList<T1,T2>
    - - - - -SortedListEnumerator - - -
    -public class SortedListEnumerator
    - - - - -SortedListIndexer - - -
    -public class SortedListIndexer
    - - - - Stack @@ -168,7 +123,7 @@

    public class Stack - + Stack<T1> @@ -177,7 +132,7 @@

    public template Stack<T1> - + StackEnumerator @@ -186,7 +141,7 @@

    public class StackEnumerator - + Tuple<T1> @@ -195,7 +150,7 @@

    public template Tuple<T1> - + Tuple<T1,T2> @@ -204,7 +159,7 @@

    public template Tuple<T1,T2> - + Tuple<T1,T2,T3> @@ -213,7 +168,7 @@

    public template Tuple<T1,T2,T3> - + Tuple<T1,T2,T3,T4> @@ -222,7 +177,7 @@

    public template Tuple<T1,T2,T3,T4> - + Tuple<T1,T2,T3,T4,T5> @@ -231,7 +186,7 @@

    public template Tuple<T1,T2,T3,T4,T5> - + Tuple<T1,T2,T3,T4,T5,T6> @@ -240,7 +195,7 @@

    public template Tuple<T1,T2,T3,T4,T5,T6> - + VarTuple<T1,T2> diff --git a/doc/api/system-collections-threadsafe-summary.html b/doc/api/system-collections-threadsafe-summary.html new file mode 100644 index 000000000..2fa2b3bd2 --- /dev/null +++ b/doc/api/system-collections-threadsafe-summary.html @@ -0,0 +1,164 @@ + + + + +ELENA Standard Library 6.3: Module system'collections'threadsafe + + + + + +
    + +
    + +ELENA Standard Library
    6.3 +
    +
    +
    +
    +

    +Module system'collections'threadsafe +

    +
    +
    +
    +
    +
    +
      +
    • + +
      +Class Summary +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Class nameDescription
      +Array<T1> + +
      +public template Array<T1>
      +
      +BaseEnumerator<T1> + +
      +abstract public template BaseEnumerator<T1>
      +
      +BaseIndexer<T1> + +
      +abstract public template BaseIndexer<T1>
      +
      +Enumerable<T1> + +
      +abstract public template Enumerable<T1>
      +
      +Enumerator<T1> + +
      +abstract public template Enumerator<T1>
      +
      +Indexable<T1> + +
      +abstract public template Indexable<T1>
      +
      +Indexer<T1> + +
      +abstract public template Indexer<T1>
      +
      +List<T1> + +
      +public template List<T1>
      +
      +Queue<T1> + +
      +public template Queue<T1>
      +
      +Reference<T1> + +
      +public template Reference<T1>
      +
      +ThreadsafeQueue<T1> + +
      +public template ThreadsafeQueue<T1>
      +
      +
    • +
    +
    +
    + +
    + +ELENA Standard Library
    6.3 +
    +
    +
    + + diff --git a/doc/api/system-collections-threadsafe.html b/doc/api/system-collections-threadsafe.html new file mode 100644 index 000000000..76ba89364 --- /dev/null +++ b/doc/api/system-collections-threadsafe.html @@ -0,0 +1,1725 @@ + + + + +ELENA Standard Library 6.3: Module system'collections'threadsafe + + + + + +
    + +
    + +ELENA Standard Library
    6.3 +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    Array<T1>

    +
    +
    +
    +
    +
    +
    +public template Array<T1>
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + +
      Modifier and TypeField
      + + +array +
      +
    • +
    + + + +
      +
    • +

      Static Property Summary

      + + + + + + + + + + + + + +
      Modifier and TypeStatic Property
      + +get  T1[] +Default() +
      + +get  T1[] +MinValue() +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +Length() +
      +
    • +
    + +
      +
    • +

      Conversion Summary

      + + + + + + + + + +
      Modifier and TypeConversion Method
      + +Enumerable +cast() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + +Indexer<T1> +indexer() + +
      + + +at(n) + +
      + + +setAt(n, item) + +
      + +Enumerator<T1> +enumerator() + +
      + +T1 +at(IntNumber n) + +
      + + +setAt(IntNumber n, T1 item) + +
      + +T1[] +add(T1[] a) + +
      + +T1[] +add(T1[] a, IntNumber length) + +
      + +T1[] +clone() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    BaseEnumerator<T1>

    +
    +
    +
    +
    +
    +
    +abstract public template BaseEnumerator<T1>
    +
    +
    + + + + +
      +
    • +

      Conversion Summary

      + + + + + + + + + +
      Modifier and TypeConversion Method
      + +Enumerator +cast() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + +BoolValue +next() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    BaseIndexer<T1>

    +
    +
    +
    +
    +
    +
    +abstract public template BaseIndexer<T1>
    +
    +
    + + + + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  BoolValue +Available() +
      + +get  IntNumber +Index() +
      + +set   +Index(IntNumber index) + +
      + +get  IntNumber +Length() +
      +
    • +
    + +
      +
    • +

      Conversion Summary

      + + + + + + + + + +
      Modifier and TypeConversion Method
      + +Indexer +cast() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + + +appendIndex(IntNumber offs) + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    Enumerable<T1>

    +
    +
    +
    +
    +
    +
    +abstract public template Enumerable<T1>
    +
    +
    +
      +
    • +system'Object
    • +
    • +
        +
      • +system'collections'threadsafe'Enumerable<T1>
      • +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + +abstract  Enumerator<T1> +enumerator() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    Enumerator<T1>

    +
    +
    +
    +
    +
    +
    +abstract public template Enumerator<T1>
    +
    +
    +
      +
    • +system'Object
    • +
    • +
        +
      • +system'collections'threadsafe'Enumerator<T1>
      • +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + +
      Modifier and TypeProperty
      + +get abstract  T1 +Value() +
      +Returns the current object
      +
      +
    • +
    + +
      +
    • +

      Conversion Summary

      + + + + + + + + + +
      Modifier and TypeConversion Method
      + +abstract  Enumerator +cast() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + +abstract  BoolValue +next() + +
      + +abstract   +reset() + +
      + +abstract   +enumerable() + +
      + +Enumerator<T1> +enumerator() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    Indexable<T1>

    +
    +
    +
    +
    +
    +
    +abstract public template Indexable<T1>
    +
    +
    +
      +
    • +system'Object
    • +
    • +
        +
      • +system'collections'threadsafe'Indexable<T1>
      • +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + +abstract  Indexer<T1> +indexer() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    Indexer<T1>

    +
    +
    +
    +
    +
    +
    +abstract public template Indexer<T1>
    +
    +
    +
      +
    • +system'Object
    • +
    • +
        +
      • +system'collections'threadsafe'Indexer<T1>
      • +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get abstract  BoolValue +Available() +
      + +get abstract  T1 +Value() +
      + +set abstract   +Value(T1 value) + +
      + +get abstract  IntNumber +Index() +
      + +set abstract   +Index(IntNumber value) + +
      + +get abstract  IntNumber +Length() +
      +
    • +
    + +
      +
    • +

      Conversion Summary

      + + + + + + + + + +
      Modifier and TypeConversion Method
      + +abstract  Indexer +cast() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + +abstract   +appendIndex(IntNumber index) + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    List<T1>

    +
    +
    +
    +
    +
    +
    +public template List<T1>
    +
    +
    + + + + + + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +Length() +
      + +get  T1 +First() +
      + +get  T1[] +Value() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + +Enumerator<T1> +enumerator() + +
      + +T1 +at(IntNumber index) + +
      + + +setAt(IntNumber index, T1 object) + +
      + + +append(T1 object) + +
      + + +appendRange(Enumerator<T1> e) + +
      + + +insert(IntNumber index, T1 object) + +
      + + +insert(T1 object) + +
      + + +remove(IntNumber index) + +
      + + +clear() + +
      + + +trim(IntNumber pos) + +
      + +Indexer<T1> +indexer() + +
      + + +clone() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    Queue<T1>

    +
    +
    +
    +
    +
    +
    +public template Queue<T1>
    +
    +
    + + + + +
      +
    • +

      Constructor / Static Method Summary

      + + + + + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +Queue<T1> +constructor() + +
      + +Queue<T1> +allocate(IntNumber capacity) + +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +Length() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + +Enumerator<T1> +enumerator() + +
      + +BoolValue +isEmpty() + +
      + +BoolValue +isNotEmpty() + +
      + + +push(T1 object) + +
      + +T1 +peek() + +
      + +T1 +pop() + +
      + + +clear() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    Reference<T1>

    +
    +
    +
    +
    +
    +
    +public template Reference<T1>
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + +
      Modifier and TypeField
      + +T1 +value +
      +
    • +
    + +
      +
    • +

      Constructor / Static Method Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +Reference<T1> +constructor(T1 val) + +
      +Initializes a variable
      +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  T1 +Value() +
      +Returns the variable value
      +
      + +set   +Value(T1 val) + +
      +Set the variable value
      +
      +
    • +
    + +
      +
    • +

      Conversion Summary

      + + + + + + + + + +
      Modifier and TypeConversion Method
      + +T1 +cast() +
      +Returns the variable value
      +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + +BoolValue +equal(o) + +
      +Returns true if o is equal to the variable value; otherwise, false
      +
      + +String +toPrintable() + +
      +Returns the value string representation
      +
      + + +dispatch() + +
      +
    • +
    +
    +
    + + + +
    +
    +system'collections'threadsafe'
    +

    ThreadsafeQueue<T1>

    +
    +
    +
    +
    +
    +
    +public template ThreadsafeQueue<T1>
    +
    +
    +
      +
    • +system'Object
    • +
    • +
        +
      • +system'collections'threadsafe'ThreadsafeQueue<T1>
      • +
      +
    • +
    + + + +
      +
    • +

      Constructor / Static Method Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +ThreadsafeQueue<T1> +constructor() + +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +Length() +
      + +get  Queue<T1> +Snapshot() +
      +Returns a copy of the queue
      +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + + +push(T1 object) + +
      + +T1 +pop() + +
      + + +clear() + +
      +
    • +
    +
    +
    +
    + +
    + +ELENA Standard Library
    6.3 +
    +
    +
    + + diff --git a/doc/api/system-collections.html b/doc/api/system-collections.html index ac719ab1a..5649566ce 100644 --- a/doc/api/system-collections.html +++ b/doc/api/system-collections.html @@ -1937,1003 +1937,6 @@

    Method Summary


    - - - -
    -
    -system'collections'
    -

    SortedArrayList

    -
    -
    -
    -
    -
    -
    -public class SortedArrayList
    -
    -
    - - - - - - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  IntNumber -Length() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - -Indexer -indexer() - -
      - - -append(Object key, Object item) - -
      - - -at(IntNumber index) - -
      - - -setAt(IntNumber index, Object o) - -
      - - -remove(IntNumber index) - -
      - - -clear() - -
      - - -trim(IntNumber pos) - -
      - -Enumerator -enumerator() - -
      -
    • -
    -
    -
    - - - -
    -
    -system'collections'
    -

    SortedList

    -
    -
    -
    -
    -
    -
    -public class SortedList
    -
    -
    - - - - - - -
      -
    • -

      Property Summary

      - - - - - - - - - - - - - -
      Modifier and TypeProperty
      - -get  IntNumber -Length() -
      - -get internal  SortedListItem -FirstItem() -
      -
    • -
    - - -
    -
    - - - -
    -
    -system'
    -

    SortedList<T1,T2>

    -
    -
    -
    -
    -
    -
    -public template SortedList<T1,T2>
    -
    -
    - - - - - - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  IntNumber -Length() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - -Enumerator<T2> -enumerator() - -
      - - -append(T1 key, T2 item) - -
      - -T2 -at(IntNumber index) - -
      - - -setAt(IntNumber index, T2 o) - -
      - - -remove(IntNumber index) - -
      - - -clear() - -
      - - -trim(IntNumber pos) - -
      - -Indexer<T2> -indexer() - -
      -
    • -
    -
    -
    - - - -
    -
    -system'collections'
    -

    SortedListEnumerator

    -
    -
    -
    -
    -
    -
    -public class SortedListEnumerator
    -
    -
    - - - - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -SortedListEnumerator -constructor(SortedList list) - -
      -
    • -
    - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get   -Value() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - -BoolValue -next() - -
      - - -reset() - -
      - - -enumerable() - -
      -
    • -
    -
    -
    - - - -
    -
    -system'collections'
    -

    SortedListIndexer

    -
    -
    -
    -
    -
    -
    -public class SortedListIndexer
    -
    -
    - - - - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -SortedListIndexer -constructor(SortedList list) - -
      -
    • -
    - -
      -
    • -

      Property Summary

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Modifier and TypeProperty
      - -get  BoolValue -Available() -
      - -get   -Value() -
      - -set   -Value(value) - -
      - -get  IntNumber -Index() -
      - -set   -Index(IntNumber value) - -
      - -get  IntNumber -Length() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - -
      Modifier and TypeMethod
      - - -appendIndex(IntNumber index) - -
      -
    • -
    -
    -
    diff --git a/doc/api/system-culture-summary.html b/doc/api/system-culture-summary.html index 94da28c82..145dfc262 100644 --- a/doc/api/system-culture-summary.html +++ b/doc/api/system-culture-summary.html @@ -107,8 +107,7 @@

    -public class WideString
    -A UTF-16 literal value
    +public class WideString diff --git a/doc/api/system-culture.html b/doc/api/system-culture.html index b68e8bc87..04c694dfb 100644 --- a/doc/api/system-culture.html +++ b/doc/api/system-culture.html @@ -337,8 +337,7 @@

    WideString



    -public class WideString
    -A UTF-16 literal value
    +public class WideString
    diff --git a/doc/api/system-drawing-summary.html b/doc/api/system-drawing-summary.html index 5091310b4..a6cd4d184 100644 --- a/doc/api/system-drawing-summary.html +++ b/doc/api/system-drawing-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'drawing +ELENA Standard Library 6.3: Module system'drawing @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -230,7 +230,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-drawing.html b/doc/api/system-drawing.html index 82399fa47..fd32f818a 100644 --- a/doc/api/system-drawing.html +++ b/doc/api/system-drawing.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'drawing +ELENA Standard Library 6.3: Module system'drawing @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -2229,7 +2229,7 @@

    Symbol Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-dynamic-expressions-summary.html b/doc/api/system-dynamic-expressions-summary.html index 74ddef27d..93460e0d5 100644 --- a/doc/api/system-dynamic-expressions-summary.html +++ b/doc/api/system-dynamic-expressions-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'dynamic'expressions +ELENA Standard Library 6.3: Module system'dynamic'expressions @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -408,7 +408,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-dynamic-expressions.html b/doc/api/system-dynamic-expressions.html index 4d542f395..54317560d 100644 --- a/doc/api/system-dynamic-expressions.html +++ b/doc/api/system-dynamic-expressions.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'dynamic'expressions +ELENA Standard Library 6.3: Module system'dynamic'expressions @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -5859,7 +5859,7 @@

    Constructor / Static Method Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-dynamic-summary.html b/doc/api/system-dynamic-summary.html index 1b1ae6138..5ff8d653b 100644 --- a/doc/api/system-dynamic-summary.html +++ b/doc/api/system-dynamic-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'dynamic +ELENA Standard Library 6.3: Module system'dynamic @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -275,7 +275,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-dynamic.html b/doc/api/system-dynamic.html index fcb208180..bc471f14b 100644 --- a/doc/api/system-dynamic.html +++ b/doc/api/system-dynamic.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'dynamic +ELENA Standard Library 6.3: Module system'dynamic @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -2427,7 +2427,7 @@

    Extension Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-io-summary.html b/doc/api/system-io-summary.html index afe5f1f56..9e83ae56e 100644 --- a/doc/api/system-io-summary.html +++ b/doc/api/system-io-summary.html @@ -44,42 +44,6 @@

    -BaseTextReader - - -
    -abstract public class BaseTextReader
    - - - - -BaseTextWriter - - -
    -abstract public class BaseTextWriter
    - - - - -BinaryReader - - -
    -abstract public class BinaryReader
    - - - - -BinaryStreamReader - - -
    -public class BinaryStreamReader
    - - - - BinaryStreamWriter @@ -161,24 +125,6 @@

    -MemoryBuffer - - -
    -public class MemoryBuffer
    - - - - -MemoryStream - - -
    -public class MemoryStream
    - - - - SearchDirectories diff --git a/doc/api/system-io.html b/doc/api/system-io.html index f382e0663..dc599516f 100644 --- a/doc/api/system-io.html +++ b/doc/api/system-io.html @@ -23,20 +23,20 @@ - +
    system'io'
    -

    BaseTextReader

    +

    BinaryStreamWriter



    -abstract public class BaseTextReader
    +public class BinaryStreamWriter
    - +
    • -

      Method Summary

      +

      Constructor / Static Method Summary

      - + - - - - +BinaryStreamWriter @@ -123,20 +98,20 @@

      Method Summary


      - +
      system'io'
      -

      BaseTextWriter

      +

      BinaryWriter



      -abstract public class BaseTextWriter
      +abstract public class BinaryWriter
        @@ -145,13 +120,7 @@

        BaseTextWriter

      @@ -167,106 +136,14 @@

      Field Summary

      - - - - - - - - - - -
      Modifier and TypeMethodConstructor / Static Method
      -String -readLine() - -
      - -WideString -readWideLine() +constructor(Stream stream)
      -TextBuilder -_buffer -
      - -String -_newLineConstant -
      - -IntNumber -_newLineLength -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - - - - - - - +Stream
      Modifier and TypeMethod
      - - -write(String line) - -
      - - -write(WideString line) - -
      - - -writeLine(line) - -
      - - -writeLine() - +_stream
    -
    -
    - - - -
    -
    -system'io'
    -

    BinaryReader

    -
    -
    -
    -
    -
    -
    -abstract public class BinaryReader
    -
    -
    -
    - +
    system'io'
    -

    BinaryStreamReader

    +

    ConsoleReader



    -public class BinaryStreamReader
    +public class ConsoleReader

    - +
    system'io'
    -

    BinaryStreamWriter

    +

    ConsoleWriter



    -public class BinaryStreamWriter
    +public class ConsoleWriter
    - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  Object -Source() -
      -
    • -
    -
    -
    - - - -
    -
    -system'io'
    -

    BinaryWriter

    -
    -
    -
    -
    -
    -
    -abstract public class BinaryWriter
    -
    -
    - - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get abstract  Object -Source() -
      -
    • -
    - - -
    -
    - - - -
    -
    -system'io'
    -

    ConsoleReader

    -
    -
    -
    -
    -
    -
    -public class ConsoleReader
    -
    -
    - - -
      -
    • -

      Field Summary

      - - - - - - - - - -
      Modifier and TypeField
      - -Handle -h -
      -
    • -
    - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -ConsoleReader -constructor(Handle h) - -
      -
    • -
    - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  BoolValue -KeyAvailable() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - -String -readLine() - -
      - -WideString -readWideLine() - -
      - -CharValue -read() - -
      -
    • -
    -
    -
    - - - -
    -
    -system'io'
    -

    ConsoleWriter

    -
    -
    -
    -
    -
    -
    -public class ConsoleWriter
    -
    -
    - - -
      -
    • -

      Field Summary

      - - - - - - - - - -
      Modifier and TypeField
      - -Handle -h -
      -
    • -
    - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -ConsoleWriter -constructor(Handle h) - -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - - -write(WideString s) - -
      - - -write(String s) - -
      - - -clear() - -
      - - -setCursorPosition(IntNumber x, IntNumber y) - -
      - - -refresh() - -
      -
    • -
    -
    -
    - - - -
    -
    -system'io'
    -

    Directory

    -
    -
    -
    -
    -
    -
    -public class Directory
    -
    -
    - - -
      -
    • -

      Field Summary

      - - - - - - - - - -
      Modifier and TypeField
      - -String -_path -
      -
    • -
    - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -Directory -assign(String path) - -
      -
    • -
    - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  BoolValue -Available() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - @@ -1174,7 +489,7 @@

      Method Summary

      @@ -1183,7 +498,7 @@

      Method Summary

      @@ -1192,20 +507,20 @@

      Method Summary


      - +
      system'io'
      -

      File

      +

      Directory



      -public class File
      +public class Directory
        @@ -1214,7 +529,7 @@

        File

        • -system'io'File
        • +system'io'Directory
      @@ -1250,7 +565,7 @@

      Constructor / Static Method Summary

      +Directory - - - - -
      Modifier and TypeMethod
      - -system'String[] -getFiles() - -
      - -system'String[] -getFiles(String mask) +write(String s)
      -create() +clear()
      -delete() +setCursorPosition(IntNumber x, IntNumber y)
      -File assign(String path) @@ -1276,42 +591,6 @@

      Property Summary

      Available()
      - -get  IntNumber -Length() -
      -
    • -
    - -
      -
    • -

      Conversion Summary

      - - - - - - - - - - - - -
      Modifier and TypeConversion Method
      - -String -cast() -
      - -WideString -cast() -
    @@ -1327,235 +606,36 @@

    Method Summary

    -TextReader - -textreader() - - - - - - -TextWriter - -textwriter() - - - - - - -TextWriter - -logger() - - - - - - - - -saveContent(String content) - - - - - - -String - -readContent() - - - - - - -WideString - -readWideContent() - - - - - - - - -delete() - - - - - - -
    -
    - - - -
    -
    -system'io'
    -

    FileEnumerator

    -
    -
    -
    -
    -
    -
    -public class FileEnumerator
    -
    -
    - - - - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -FileEnumerator -assign(String mask) - -
      -
    • -
    - -
      -
    • -

      Property Summary

      - - - - - - - - - -
      Modifier and TypeProperty
      - -get  WIN32_FIND_DATA -Value() -
      -
    • -
    - - - -
      -
    • -

      Method Summary

      - - - - +getFiles() + + - + +system'String[] - + - + @@ -1564,20 +644,20 @@

      Method Summary


      - +
      system'io'
      -

      FileStream

      +

      File



      -public class FileStream
      +public class File
        @@ -1586,13 +666,7 @@

        FileStream

      @@ -1608,9 +682,9 @@

      Field Summary

      +String
      Modifier and TypeMethod
      -BoolValue -next() +getFiles(String mask)
      -reset() +create()
      -enumerable() +delete()
      -Handle -_handle +_path
      @@ -1628,45 +702,9 @@

      Constructor / Static Method Summary

      -FileStream - -openForRead(path) - - - - - - -FileStream - -openForReWrite(path) - - - - - - -FileStream - -openForAppend(path) - - - - - - -FileStream - -openForEdit(path) - - - - - - -FileStream +File
      -new(WideString path, IntNumber dwDesiredAccess, IntNumber dwShareMode, IntNumber dwCreationDisposition, IntNumber dwFlagsAndAttributes) +assign(String path) @@ -1685,35 +723,45 @@

      Property Summary

      -get  IntNumber +get  BoolValue
      -Length() +Available() -set   +get  IntNumber -Length(IntNumber length) - +Length() + +
    • +
    + + -
    -
    - - - -
    -
    -system'io'
    -

    IOException

    -
    -
    -
    -
    -
    -
    -public class IOException
    -
    -
    - - -
      -
    • -

      Field Summary

      - - - - - - + + - + +String -
      Modifier and TypeField
      -String -message +saveContent(String content) +
      -CallStack -callStack +readContent() +
      -
    • -
    - -
    - + + +
    + + + +
    +
    +system'io'
    +

    IOException

    +
    +
    +
    +
    +
    +
    +public class IOException
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + +
      Modifier and TypeField
      + +String +message +
      + +CallStack +callStack +
      +
    • +
    + +
      +
    • +

      Constructor / Static Method Summary

      + + + + + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +IOException +new() + +
      + +IOException +new(String message) + +
      +
    • +
    +
    +
    @@ -2472,18 +1559,12 @@

    StreamWriter

  • - -
    @@ -2587,9 +1677,9 @@

    Property Summary

    -get  Object +get  Stream
    -Source() +Stream() @@ -2661,6 +1751,42 @@

    TextReader

    + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeField
      + +TextBuilder +_output +
      + +String +_newLineConstant +
      + +IntNumber +_newLineLength +
      +
    • +
    • @@ -2673,9 +1799,9 @@

      Property Summary

      -get abstract  Object +get abstract  Stream -Source() +Stream() @@ -2727,7 +1853,7 @@

      Method Summary

      -abstract  String +String readLine() @@ -2736,7 +1862,7 @@

      Method Summary

      -abstract  WideString +WideString readWideLine() @@ -2773,18 +1899,12 @@

      TextStreamReader

    - -
    • @@ -2896,9 +2016,9 @@

      Property Summary

      -get  Object +get  Stream -Source() +Stream() @@ -2978,6 +2098,42 @@

      TextWriter

    + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeField
      + +TextBuilder +_buffer +
      + +String +_newLineConstant +
      + +IntNumber +_newLineLength +
      +
    • +
    • @@ -2990,9 +2146,9 @@

      Property Summary

      -get abstract  Object +get abstract  Stream -Source() +Stream() @@ -3045,34 +2201,34 @@

      Method Summary

      -abstract   + -write(String line) +writeLine(line) -abstract   + -write(WideString line) +write(String line) -abstract   + -writeLine(line) +write(WideString line) -abstract   + writeLine() diff --git a/doc/api/system-math-summary.html b/doc/api/system-math-summary.html index 83f469503..9008b2c20 100644 --- a/doc/api/system-math-summary.html +++ b/doc/api/system-math-summary.html @@ -47,35 +47,6 @@

    • -Symbol Summary -
      - - - - - - - - - - - - -
      Symbol nameDescription
      -E - -
      -E
      -
      -Pi - -
      -Pi
      -
      -
    • -
    • - -
      Extended Class Summary
      diff --git a/doc/api/system-math.html b/doc/api/system-math.html index 18463f15f..82b8b6ddc 100644 --- a/doc/api/system-math.html +++ b/doc/api/system-math.html @@ -23,80 +23,6 @@ - - - -
      -
      -system'math'
      -

      E

      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
        -
      • -

        Symbol Summary

        -
      - - - - - - -
      Modifier and TypeName
      - -public  RealNumber -E -
      -
    • -

    - -
    - - - - -
    -
    -system'math'
    -

    Pi

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
      -
    • -

      Symbol Summary

      - - - - - - - -
      Modifier and TypeName
      - -public  RealNumber -Pi -
      -
    • -
    -
    -
    -
    diff --git a/doc/api/system-net-summary.html b/doc/api/system-net-summary.html index c7a13562e..d11eb0015 100644 --- a/doc/api/system-net-summary.html +++ b/doc/api/system-net-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'net +ELENA Standard Library 6.3: Module system'net @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -239,7 +239,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-net.html b/doc/api/system-net.html index 7dfca91d0..8e016f89b 100644 --- a/doc/api/system-net.html +++ b/doc/api/system-net.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'net +ELENA Standard Library 6.3: Module system'net @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -1349,7 +1349,7 @@

    Symbol Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-routines-summary.html b/doc/api/system-routines-summary.html index 7acb9a45f..d22bc33f9 100644 --- a/doc/api/system-routines-summary.html +++ b/doc/api/system-routines-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'routines +ELENA Standard Library 6.3: Module system'routines @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -329,7 +329,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-routines.html b/doc/api/system-routines.html index 6f7de81c7..3475ccc4a 100644 --- a/doc/api/system-routines.html +++ b/doc/api/system-routines.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'routines +ELENA Standard Library 6.3: Module system'routines @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -3996,7 +3996,7 @@

    Extension Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-runtime-summary.html b/doc/api/system-runtime-summary.html index 8a2f9c645..136906697 100644 --- a/doc/api/system-runtime-summary.html +++ b/doc/api/system-runtime-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'runtime +ELENA Standard Library 6.3: Module system'runtime @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -44,6 +44,15 @@

    +Environment + + +
    +public singleton Environment
    + + + + GCHeapInfo @@ -51,7 +60,7 @@

    public class GCHeapInfo - + GCManager @@ -60,7 +69,7 @@

    public singleton GCManager - + GCStatistics @@ -69,7 +78,7 @@

    public class GCStatistics - + Package @@ -78,7 +87,7 @@

    public class Package - + PermVectorTable @@ -87,6 +96,80 @@

    public singleton PermVectorTable + + +ProcessorType + + +
    +public class ProcessorType
    + + + + +
  • + +
    +Symbol Summary +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Symbol nameDescription
    +PROCESSOR_ARCHITECTURE_AMD64 + +
    +PROCESSOR_ARCHITECTURE_AMD64
    +
    +PROCESSOR_ARCHITECTURE_ARM + +
    +PROCESSOR_ARCHITECTURE_ARM
    +
    +PROCESSOR_ARCHITECTURE_ARM64 + +
    +PROCESSOR_ARCHITECTURE_ARM64
    +
    +PROCESSOR_ARCHITECTURE_IA64 + +
    +PROCESSOR_ARCHITECTURE_IA64
    +
    +PROCESSOR_ARCHITECTURE_INTEL + +
    +PROCESSOR_ARCHITECTURE_INTEL
    +
    +PROCESSOR_ARCHITECTURE_UNKNOWN + +
    +PROCESSOR_ARCHITECTURE_UNKNOWN
    +
  • @@ -122,7 +205,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-runtime.html b/doc/api/system-runtime.html index a017fda75..94bc35db1 100644 --- a/doc/api/system-runtime.html +++ b/doc/api/system-runtime.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'runtime +ELENA Standard Library 6.3: Module system'runtime @@ -19,10 +19,66 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    + + + +
    +
    +system'runtime'
    +

    Environment

    +
    +
    +
    +
    +
    +
    +public singleton Environment
    +
    +
    + + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +ProcessorCount() +
      + +get  ProcessorType +ProcessorType() +
      +
    • +
    +
    +
    @@ -395,6 +451,276 @@

    Method Summary


    + + + +
    +
    +system'runtime'
    +

    ProcessorType

    +
    +
    +
    +
    +
    +
    +public class ProcessorType
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + +
      Modifier and TypeField
      + +IntNumber +_value +
      +
    • +
    +
    +
    + + + +
    +
    +system'runtime'
    +

    PROCESSOR_ARCHITECTURE_AMD64

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +PROCESSOR_ARCHITECTURE_AMD64 +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'runtime'
    +

    PROCESSOR_ARCHITECTURE_ARM

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +PROCESSOR_ARCHITECTURE_ARM +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'runtime'
    +

    PROCESSOR_ARCHITECTURE_ARM64

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +PROCESSOR_ARCHITECTURE_ARM64 +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'runtime'
    +

    PROCESSOR_ARCHITECTURE_IA64

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +PROCESSOR_ARCHITECTURE_IA64 +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'runtime'
    +

    PROCESSOR_ARCHITECTURE_INTEL

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +PROCESSOR_ARCHITECTURE_INTEL +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'runtime'
    +

    PROCESSOR_ARCHITECTURE_UNKNOWN

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +PROCESSOR_ARCHITECTURE_UNKNOWN +
      +
    • +
    +
    +
    +
    @@ -445,7 +771,7 @@

    Extension Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-summary.html b/doc/api/system-summary.html index 4b942355a..2b99cc4e3 100644 --- a/doc/api/system-summary.html +++ b/doc/api/system-summary.html @@ -90,15 +90,6 @@

    -BaseEnumerator - - -
    -abstract public class BaseEnumerator
    - - - - BaseEnumerator<T1> @@ -106,7 +97,7 @@

    abstract public template BaseEnumerator<T1> - + BaseExtender @@ -115,7 +106,7 @@

    public class BaseExtender - + BaseIndexer @@ -124,7 +115,7 @@

    abstract public class BaseIndexer - + BaseIndexer<T1> @@ -133,7 +124,7 @@

    abstract public template BaseIndexer<T1> - + BaseLazyExpression @@ -142,7 +133,7 @@

    abstract public class BaseLazyExpression - + BaseNumber @@ -152,7 +143,7 @@

    a base numeric value - + BaseValue @@ -162,7 +153,7 @@

    a base value - + BaseVariable @@ -172,7 +163,7 @@

    variable base class - + BitArray @@ -181,7 +172,7 @@

    public class BitArray - + BitArray32 @@ -190,7 +181,7 @@

    public class BitArray32 - + BoolValue @@ -200,7 +191,7 @@

    a common boolean value - + BoolValue#false @@ -209,7 +200,7 @@

    public singleton BoolValue#false - + BoolValue#true @@ -218,7 +209,7 @@

    public singleton BoolValue#true - + byteArrayConvertor @@ -227,7 +218,7 @@

    public singleton byteArrayConvertor - + byteConvertor @@ -236,7 +227,7 @@

    public singleton byteConvertor - + ByteNumber @@ -246,7 +237,7 @@

    an unsigned 8 bit integer - + CallStack @@ -256,7 +247,7 @@

    A call stack - + charConvertor @@ -265,7 +256,7 @@

    public singleton charConvertor - + CharValue @@ -275,7 +266,7 @@

    An UTF-32 character symbol - + ClassReference @@ -284,7 +275,7 @@

    public class ClassReference - + Console @@ -293,7 +284,7 @@

    public class Console - + COORD @@ -302,7 +293,7 @@

    public class COORD - + CriticalException @@ -311,7 +302,7 @@

    public class CriticalException - + DivisionByZeroException @@ -320,7 +311,7 @@

    public class DivisionByZeroException - + Enumerable @@ -329,7 +320,7 @@

    abstract public class Enumerable - + Enumerable<T1> @@ -338,7 +329,7 @@

    abstract public template Enumerable<T1> - + Enumerator @@ -348,7 +339,7 @@

    An enumerator prototype - + Enumerator<T1> @@ -357,17 +348,16 @@

    abstract public template Enumerator<T1> - + Exception
    -public class Exception
    -A basic exception
    +public class Exception - + Extension @@ -376,7 +366,7 @@

    public class Extension - + ExtensionMessage @@ -386,7 +376,7 @@

    An extended message constant - + ExtensionVariable @@ -395,7 +385,7 @@

    public class ExtensionVariable - + FormatException @@ -404,7 +394,7 @@

    public class FormatException - + Func @@ -414,15 +404,6 @@

    A base action - - -Func<T1,T1,system'IntNumber> - - -
    -abstract public template Func<T1,T1,system'IntNumber>
    - - Func<T1,T2> @@ -721,8 +702,7 @@

    -public class Message
    -A message constant
    +public class Message @@ -921,15 +901,6 @@

    -StartUpEvents - - -
    -public class StartUpEvents
    - - - - String @@ -938,7 +909,7 @@

    A UTF-8 literal value - + stringConvertor @@ -947,7 +918,7 @@

    public singleton stringConvertor - + Symbol @@ -956,7 +927,7 @@

    public class Symbol - + SymbolLoaderException @@ -965,7 +936,7 @@

    public class SymbolLoaderException - + TypeLoaderException @@ -974,7 +945,7 @@

    public class TypeLoaderException - + uintConvertor @@ -983,7 +954,7 @@

    public singleton uintConvertor - + UIntNumber @@ -993,7 +964,7 @@

    A unsigned 32 bit integer - + UnsafePointer @@ -1002,7 +973,7 @@

    public class UnsafePointer - + ushortConvertor @@ -1011,7 +982,7 @@

    public singleton ushortConvertor - + UShortNumber @@ -1021,7 +992,7 @@

    an unsigned 16 bit integer - + Variable @@ -1031,7 +1002,7 @@

    A generic variable.
    Extends an assigned value
    - + Variant @@ -1041,7 +1012,7 @@

    A basic type variant class - + wideConvertor @@ -1050,14 +1021,13 @@

    public singleton wideConvertor - + WideString
    -public class WideString
    -A UTF-16 literal value
    +public class WideString @@ -1145,15 +1115,6 @@

    -startUpEvents - - -
    -startUpEvents
    - - - - true diff --git a/doc/api/system-text-summary.html b/doc/api/system-text-summary.html index 7c2c149a8..3de4a3e16 100644 --- a/doc/api/system-text-summary.html +++ b/doc/api/system-text-summary.html @@ -53,15 +53,6 @@

    -StringBuilder - - -
    -public class StringBuilder
    - - - - TextBuilder @@ -69,7 +60,7 @@

    public class TextBuilder - + UTF16Encoder @@ -78,7 +69,7 @@

    public singleton UTF16Encoder - + UTF16Encoding @@ -87,7 +78,7 @@

    public singleton UTF16Encoding - + UTF8Encoder @@ -96,7 +87,7 @@

    public singleton UTF8Encoder - + UTF8Encoding @@ -105,15 +96,6 @@

    public singleton UTF8Encoding - - -WideStringBuilder - - -
    -public class WideStringBuilder
    - - WinEncoder diff --git a/doc/api/system-text.html b/doc/api/system-text.html index 960785d85..0f188f137 100644 --- a/doc/api/system-text.html +++ b/doc/api/system-text.html @@ -126,186 +126,6 @@

    Method Summary


    - - - -
    -
    -system'text'
    -

    StringBuilder

    -
    -
    -
    -
    -
    -
    -public class StringBuilder
    -
    -
    - - - - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -StringBuilder -constructor() - -
      -
    • -
    - -
      -
    • -

      Property Summary

      - - - - - - - - - - - - - -
      Modifier and TypeProperty
      - -get  IntNumber -Length() -
      - -get  String -Value() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - - -insert(index, o) - -
      - - -write(CharValue ch) - -
      - - -write(String s) - -
      - - -wide(o) - -
      - - -insert(IntNumber index, CharValue ch) - -
      - - -insert(IntNumber index, String s) - -
      - - -delete(IntNumber index, IntNumber length) - -
      -
    • -
    -
    -
    @@ -766,7 +586,7 @@

    Method Summary

    CharValue -convertToChar(system'ByteNumber[] byteArray, IntNumber index, ref IntNumber chLen) +convertToChar(system'ByteNumber[] byteArray, IntNumber index, ref IntNumber length) @@ -849,15 +669,6 @@

    Method Summary

    - - -toShortArray(CharValue ch, system'ShortNumber[] output, IntNumber outputIndex, ref IntNumber len) - - - - - - IntNumber getCharCount(WideString s) @@ -1000,186 +811,6 @@

    Method Summary


    - - - -
    -
    -system'text'
    -

    WideStringBuilder

    -
    -
    -
    -
    -
    -
    -public class WideStringBuilder
    -
    -
    - - - - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -WideStringBuilder -constructor() - -
      -
    • -
    - -
      -
    • -

      Property Summary

      - - - - - - - - - - - - - -
      Modifier and TypeProperty
      - -get  IntNumber -Length() -
      - -get  String -Value() -
      -
    • -
    - - -
    -
    diff --git a/doc/api/system-threading-summary.html b/doc/api/system-threading-summary.html index 5568392cf..cfc793038 100644 --- a/doc/api/system-threading-summary.html +++ b/doc/api/system-threading-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'threading +ELENA Standard Library 6.3: Module system'threading @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -44,20 +44,20 @@

    -Thread +Semaphore
    -public class Thread
    +public class Semaphore -threadControl +Thread
    -public singleton threadControl
    +public class Thread @@ -69,6 +69,24 @@

    public class ThreadHandle + + +ThreadPool + + +
    +public class ThreadPool
    + + + + +ThreadPriority + + +
    +public class ThreadPriority
    + +

  • @@ -89,6 +107,69 @@

    INFINITE + + +THREAD_PRIORITY_ABOVE_NORMAL + + +
    +THREAD_PRIORITY_ABOVE_NORMAL
    + + + + +THREAD_PRIORITY_BELOW_NORMAL + + +
    +THREAD_PRIORITY_BELOW_NORMAL
    + + + + +THREAD_PRIORITY_HIGHEST + + +
    +THREAD_PRIORITY_HIGHEST
    + + + + +THREAD_PRIORITY_LOWEST + + +
    +THREAD_PRIORITY_LOWEST
    + + + + +THREAD_PRIORITY_NORMAL + + +
    +THREAD_PRIORITY_NORMAL
    + + + + +WAIT_OBJECT_0 + + +
    +WAIT_OBJECT_0
    + + + + +WAIT_TIMEOUT + + +
    +WAIT_TIMEOUT
    + +

  • @@ -104,7 +185,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-threading.html b/doc/api/system-threading.html index ea4cad9d8..9f9d7e400 100644 --- a/doc/api/system-threading.html +++ b/doc/api/system-threading.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'threading +ELENA Standard Library 6.3: Module system'threading @@ -19,24 +19,24 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    - +
    system'threading'
    -

    Thread

    +

    Semaphore



    -public class Thread
    +public class Semaphore
      @@ -45,7 +45,7 @@

      Thread

      • -system'threading'Thread
      • +system'threading'Semaphore
    @@ -61,7 +61,7 @@

    Field Summary

    -ThreadHandle +Handle
    _handle @@ -81,9 +81,9 @@

    Constructor / Static Method Summary

    -Thread +Semaphore
    -assign(Func f) +create(IntNumber initValue, IntNumber maxValue) @@ -104,7 +104,7 @@

    Method Summary

    -start() +close() @@ -113,7 +113,7 @@

    Method Summary

    -join() +wait() @@ -122,7 +122,7 @@

    Method Summary

    -close() +release() @@ -131,20 +131,20 @@

    Method Summary


    - +
    system'threading'
    -

    threadControl

    +

    Thread



    -public singleton threadControl
    +public class Thread
      @@ -153,8 +153,159 @@

      threadControl

      • -system'threading'threadControl
      • +system'threading'Thread +
      +
    • +
    + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + +
      Modifier and TypeField
      + +ThreadHandle +_handle +
      + +Object +_startArg +
      +
    • +
    + +
      +
    • +

      Constructor / Static Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + + +sleep(IntNumber milliseconds) + +
      + +Thread +assign(Func f) + +
      + +Thread +assign(Func f, IntNumber stackSize) + +
      + +Thread +assign(Func1 f) + +
      + +Thread +assign(Func1 f, IntNumber stackSize) + +
      + +internal  Thread +current() + +
      +
    • +
    + +
      +
    • +

      Static Property Summary

      + + + + + + + + + +
      Modifier and TypeStatic Property
      + +get  Thread +Current() +
      +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  ThreadPriority +Priority() +
      + +set   +Priority(ThreadPriority value) + +
      + +get  BoolValue +IsAlive() +
    @@ -171,7 +322,43 @@

    Method Summary

    -sleep(IntNumber interval) +start() + + + + + + + + +start(Object arg) + + + + + + + + +join() + + + + + + + + +join(IntNumber milliseconds) + + + + + + + + +close() @@ -246,9 +433,36 @@

    Constructor / Static Method Summary

    + + +sleep(IntNumber interval) + + + + + + +ThreadHandle + +constructor() + + + + + + +ThreadHandle + +constructor(Object f) + + + + + + ThreadHandle -constructor(Func f) +constructor(Object f, IntNumber stackSize) @@ -267,6 +481,24 @@

    Method Summary

    +ThreadPriority + +getPriority() + + + + + + + + +setPriority(ThreadPriority priority) + + + + + + start() @@ -294,6 +526,15 @@

    Method Summary

    +BoolValue + +checkIfAlive() + + + + + + close() @@ -305,36 +546,410 @@

    Method Summary


    - + - +
    system'threading'
    -

    INFINITE

    +

    ThreadPool



    -
    +public class ThreadPool
    -
    + +
    • -

      Symbol Summary

      +

      Constructor / Static Method Summary

      - + + +private   + + + + + + + + + +
      Modifier and TypeNameConstructor / Static Method
      -public  IntNumber -INFINITE +function:#class_init() + +
      + + +queueAction(Func f) + +
      + + +queueAction(Func1 f, Object arg) + +
      +
    • +
    +
    +
    + + + +
    +
    +system'threading'
    +

    ThreadPriority

    +
    +
    +
    +
    +
    +
    +public class ThreadPriority
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + +
      Modifier and TypeField
      + +IntNumber +_value +
      +
    • +
    +
    +
    + + + +
    +
    +system'threading'
    +

    INFINITE

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +INFINITE +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'threading'
    +

    THREAD_PRIORITY_ABOVE_NORMAL

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +THREAD_PRIORITY_ABOVE_NORMAL +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'threading'
    +

    THREAD_PRIORITY_BELOW_NORMAL

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +THREAD_PRIORITY_BELOW_NORMAL +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'threading'
    +

    THREAD_PRIORITY_HIGHEST

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +THREAD_PRIORITY_HIGHEST +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'threading'
    +

    THREAD_PRIORITY_LOWEST

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +THREAD_PRIORITY_LOWEST +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'threading'
    +

    THREAD_PRIORITY_NORMAL

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +THREAD_PRIORITY_NORMAL +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'threading'
    +

    WAIT_OBJECT_0

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +WAIT_OBJECT_0 +
      +
    • +
    +
    +
    +
    + + + +
    +
    +system'threading'
    +

    WAIT_TIMEOUT

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + +
      Modifier and TypeName
      + +public  IntNumber +WAIT_TIMEOUT
    • @@ -353,7 +968,7 @@

      Symbol Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system-winforms-summary.html b/doc/api/system-winforms-summary.html index 1dc1bce83..3228c9fe1 100644 --- a/doc/api/system-winforms-summary.html +++ b/doc/api/system-winforms-summary.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'winforms +ELENA Standard Library 6.3: Module system'winforms @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -923,7 +923,7 @@

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3

    diff --git a/doc/api/system-winforms.html b/doc/api/system-winforms.html index 0a6ad44f9..6f05883c5 100644 --- a/doc/api/system-winforms.html +++ b/doc/api/system-winforms.html @@ -2,7 +2,7 @@ -ELENA Standard Library 6.0: Module system'winforms +ELENA Standard Library 6.3: Module system'winforms @@ -19,7 +19,7 @@
    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    @@ -4662,7 +4662,7 @@

    Symbol Summary

    -ELENA Standard Library
    6.0 +ELENA Standard Library
    6.3
    diff --git a/doc/api/system.html b/doc/api/system.html index 5e67e887b..7df9a25d1 100644 --- a/doc/api/system.html +++ b/doc/api/system.html @@ -373,8 +373,6 @@

    Constructor / Static Method Summary

    copy(T1[] target, T1[] source, IntNumber index, IntNumber length) -
    -Copies a subarray from source starting at index to target
    @@ -384,8 +382,6 @@

    Constructor / Static Method Summary

    copyTo(T1[] target, T1[] source, IntNumber index, IntNumber length) -
    -Copies a source array to target at index
    @@ -889,89 +885,6 @@

    Method Summary


    - - - -
    -
    -system'
    -

    BaseEnumerator

    -
    -
    -
    -
    -
    -
    -abstract public class BaseEnumerator
    -
    -
    - - - - -
      -
    • -

      Method Summary

      - - - - - - - - - -
      Modifier and TypeMethod
      - -BoolValue -next() - -
      -
    • -
    -
    -
    @@ -4420,34 +4333,16 @@

    Extension Summary

    BoolValue -isNewLine() - - - - - - -BoolValue - isWhitespace() - - - -BoolValue - -isDigit() - - - BoolValue -isLetter() +isDigit() @@ -4623,9 +4518,9 @@

    Constructor / Static Method Summary

    -internal  Console +Console
    -constructor(IConsoleReader reader, IConsoleWriter writer) +ystem$$#constructor(IConsoleReader reader, IConsoleWriter writer) @@ -4668,8 +4563,6 @@

    Method Summary

    write(s) -
    -Writes the specified literal value to the standard output stream.
    @@ -4679,8 +4572,6 @@

    Method Summary

    writeLine(s) -
    -Writes the specified literal value, followed by the current line terminator, to the standard output stream.
    @@ -4699,8 +4590,6 @@

    Method Summary

    readChar() -
    -Reads the next character from the input stream
    @@ -4732,17 +4621,6 @@

    Method Summary

    Reads the next line of characters from the standard input stream. - - - -WideString - -readWideLine() - -
    -Reads the next line of characters from the standard input stream.
    - - @@ -5293,8 +5171,6 @@

    Property Summary

    get abstract  T1
    Value() -
    -Returns the current object
    @@ -5383,8 +5259,7 @@

    Exception



    -public class Exception
    -A basic exception
    +public class Exception
      @@ -5509,8 +5384,6 @@

      Method Summary

      toPrintable() -
      -Returns the message and the call stack
      @@ -5973,75 +5846,6 @@

      Method Summary


    - - - -
    -
    -system'
    -

    Func<T1,T1,system'IntNumber>

    -
    -
    -
    -
    -
    -
    -abstract public template Func<T1,T1,system'IntNumber>
    -
    -
    -
      -
    • -system'Object
    • -
    • -
        -
      • -system'Func<T1,T1,system'IntNumber>
      • -
      -
    • -
    - -
      -
    • -

      Conversion Summary

      - - - - - - - - - -
      Modifier and TypeConversion Method
      - -Func2 -cast() -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - -
      Modifier and TypeMethod
      - -abstract  IntNumber -function(T1 arg1, T1 arg2) - -
      -
    • -
    -
    -
    @@ -7197,20 +7001,11 @@

    Constructor / Static Method Summary

    Handle -loadDirty(IntNumber value) - - - - - - -Handle - constructor() - + Handle @@ -7423,15 +7218,6 @@

    Method Summary

    - - - -abstract   - -refresh() - - - @@ -8381,15 +8167,6 @@

    Constructor / Static Method Summary

    - - - -IntNumber - -constructor(UShortNumber s) - - - @@ -9305,22 +9082,6 @@

    Extension Summary

    - - - -get property  ShortNumber - -High() - - - - - -get property  ShortNumber - -Low() - - @@ -10698,22 +10459,6 @@

    Extension Summary

    -get property  IntNumber - -Hashcode() - - - - - -get property  LongNumber - -Absolute() - - - - - LongNumber power(LongNumber y) @@ -10828,22 +10573,6 @@

    Extension Summary

    - - - -get property  IntNumber - -High() - - - - - -get property  IntNumber - -Low() - - @@ -10862,8 +10591,7 @@

    Message



    -public class Message
    -A message constant
    +public class Message
      @@ -11724,8 +11452,6 @@

      Extension Summary

      equalReference(Object o) -
      -Returns true if the specified object instances are equal; otherwise, false.
      @@ -11773,34 +11499,10 @@

      Extension Summary

      - - -__getParentClass() - -
      -Returns the parent class
      - - - - - - - -__getParent() - -
      -Returns the parent of the specified class
      - - - - - -BoolValue +BoolValue safeEqual(Object o) -
      -Returns true if the parameter is equal to the object or false. It does not raise an exception if the objects are not compatible
      @@ -11824,24 +11526,13 @@

      Extension Summary

      -BoolValue - -isNil() - -
      -Returns true if the object is nil
      - - - - - doWith(Object action) - + BoolValue @@ -11852,58 +11543,16 @@

      Extension Summary

      Checks if the object is an instance of type - - - -BoolValue - -subsetOf(Object type) - - - - - - -BoolValue - -isLiteral() - -
      -Returns true if the object is literal or character
      - - - - - -BoolValue - -isInteger() - -
      -Returns true if the object is an integer number
      - - -BoolValue - -isNumber() - -
      -Returns true if the object is a number
      - - - - - Array Subarray(IntNumber index, IntNumber length) - + @@ -11912,7 +11561,7 @@

      Extension Summary

      - + @@ -11921,7 +11570,7 @@

      Extension Summary

      - + @@ -11930,7 +11579,7 @@

      Extension Summary

      - + @@ -11939,7 +11588,7 @@

      Extension Summary

      - + @@ -11948,7 +11597,7 @@

      Extension Summary

      - + @@ -11957,7 +11606,7 @@

      Extension Summary

      - + @@ -11966,7 +11615,7 @@

      Extension Summary

      - + @@ -11975,7 +11624,7 @@

      Extension Summary

      - + @@ -13496,20 +13145,11 @@

      Extension Summary

      RealNumber -round(IntNumber precision) - - - - - - -RealNumber - truncate(IntNumber precision) - + get property  RealNumber @@ -13517,7 +13157,7 @@

      Extension Summary

      Radian() - + get property  RealNumber @@ -13525,7 +13165,7 @@

      Extension Summary

      Degree() - + BoolValue @@ -13534,7 +13174,7 @@

      Extension Summary

      - + BoolValue @@ -13543,7 +13183,7 @@

      Extension Summary

      - + BoolValue @@ -13552,7 +13192,7 @@

      Extension Summary

      - + BoolValue @@ -16063,113 +15703,6 @@

      Method Summary


    - - - -
    -
    -system'
    -

    StartUpEvents

    -
    -
    -
    -
    -
    -
    -public class StartUpEvents
    -
    -
    - - - - -
      -
    • -

      Constructor / Static Method Summary

      - - - - - - - - - -
      Modifier and TypeConstructor / Static Method
      - -internal  StartUpEvents -constructor() - -
      -
    • -
    - -
      -
    • -

      Method Summary

      - - - - - - - - - - - - - -
      Modifier and TypeMethod
      - -internal   -stopping() - -
      - -internal   -handlingError(e) - -
      -
    • -
    -
    -
    @@ -16794,15 +16327,6 @@

    Extension Summary

    - - - -String - -replaceFirst(String replacee, String replacer) - - - @@ -18391,21 +17915,13 @@

    Extension Summary

    -get property  IntNumber - -Hashcode() - - - - - UIntNumber sqr() - + UIntNumber @@ -18414,7 +17930,7 @@

    Extension Summary

    - + UIntNumber @@ -18423,7 +17939,7 @@

    Extension Summary

    - + UIntNumber @@ -18432,7 +17948,7 @@

    Extension Summary

    - + UIntNumber @@ -18441,7 +17957,7 @@

    Extension Summary

    - + RealNumber @@ -18450,7 +17966,7 @@

    Extension Summary

    - + BoolValue @@ -18459,7 +17975,7 @@

    Extension Summary

    - + BoolValue @@ -18468,7 +17984,7 @@

    Extension Summary

    - + BoolValue @@ -18477,7 +17993,7 @@

    Extension Summary

    - + BoolValue @@ -18486,7 +18002,7 @@

    Extension Summary

    - + BoolValue @@ -18495,7 +18011,7 @@

    Extension Summary

    - + BoolValue @@ -18647,14 +18163,6 @@

    Conversion Summary

    cast() - - - -RealNumber - -cast() - - @@ -18743,15 +18251,6 @@

    Method Summary

    - - - -UShortNumber - -convert(IntNumber n) - - - @@ -20138,8 +19637,7 @@

    WideString



    -public class WideString
    -A UTF-16 literal value
    +public class WideString
      @@ -20543,206 +20041,6 @@

      Method Summary

    - -
    @@ -21041,43 +20339,6 @@

    Symbol Summary


    -
    - - -
    -
    -system'
    -

    startUpEvents

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
      -
    • -

      Symbol Summary

      - - - - - - - -
      Modifier and TypeName
      - -public  StartUpEvents -startUpEvents -
      -
    • -
    -
    -
    -
    diff --git a/doc/contributors b/doc/contributors index 07f732f07..08a9d05de 100644 --- a/doc/contributors +++ b/doc/contributors @@ -1,4 +1,4 @@ Aleksey Rakov (creator) Alexandre Bencz (examples : agenda, c_a_g, sqlite_test ..., lib : sqllite, ... and a lot of bug reports, work on asm2binx) Raymond Filiatreault / FPULIB21a (float numer routines) -Yair Bybabayov (elenavm) \ No newline at end of file +Yair Bybabayov (elenavm, elc) \ No newline at end of file diff --git a/doc/features b/doc/features index a41d3b01c..2f2bbaf81 100644 --- a/doc/features +++ b/doc/features @@ -118,3 +118,84 @@ public program() { var n := 12o; } + +---------------------------------------------------------------------------- + function reference +---------------------------------------------------------------------------- +import extensions; + +import extensions; +import system'threading; + +myFunction() +{ + console.writeLine("Hello from the thread"); +} + +public program() +{ + auto myThread := Thread.assign(&myFunction); +} + +---------------------------------------------------------------------------- + threads +---------------------------------------------------------------------------- + +-- Without argumnet --- + +import extensions; +import system'threading; + +myFunction() +{ + console.writeLine("Hello from the thread"); +} + +public program() +{ + auto myThread := Thread.assign(&myFunction); + + var priority := myThread.Priority; + + console.printLine("Thread priority ", priority); + + myThread.start(); + + console.readChar() +} + +-- With argumnet --- + +import extensions; +import system'threading; + +myFunction(arg) +{ + console.writeLine($"{arg} from the thread"); +} + +public program() +{ + auto myThread := Thread.assign(&myFunction); + + var priority := myThread.Priority; + + console.printLine("Thread priority ", priority); + + myThread.start("Good bay"); + + console.readChar() +} + +---------------------------------------------------------------------------- + Environment +---------------------------------------------------------------------------- + +import extensions; +import system'runtime; + +public program() +{ + console.writeLine($"Processor type:{Environment.ProcessorType}"); + console.writeLine($"Processor count:{Environment.ProcessorCount}"); +} diff --git a/doc/tech/bytecode60.txt b/doc/tech/bytecode60.txt index b69e2e972..28dce04e4 100644 --- a/doc/tech/bytecode60.txt +++ b/doc/tech/bytecode60.txt @@ -200,8 +200,6 @@ ELENA byte codes (or ecodes) lload sp:i - long:index := sp[i] - load fp:i - index := fp[i] - load dp:disp - index := dp[disp] load sp:i - index := sp[i] diff --git a/doc/todo.txt b/doc/todo.txt index 33e02b3e3..5d3cf61bb 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -5,32 +5,29 @@ In development: [development] ### EPIC: elena 6.4 ### - === Iteration 31 === + === Iteration 32 (19.9) === -------------------------------------- dev: - - async programming (general concept, SynchronizationContext, ThreadPool, Task, AsyncLocal, ThreadStatic) + - async programming (Task, object field (similar to Event), WaitHandle, AsyncLocal) + - ThreadLocal - upndown (connector) - - chat: add mutex (see dpa_queue) - #496 gen: - lpad : generate a code based on a record maint: - - #679 + - set up automatic tests + - #618 port: - #658 : connect with ldbg from VSCode prom: posting weekly -------------------------------------- + * x86-64 : mta - corex + * Task + * ppc64le : fix iteratorMethodTest + * thread pool testcase (https://www.c-sharpcorner.com/article/threadpool-in-c-sharp-practical-examples/) + * inline assigning functional test : template type -------------------------------------- - - === Iteration 32 === - -------------------------------------- - dev: - gen: - maint: - port: - prom: - -------------------------------------- - -------------------------------------- + * inline assigning : template type === Iteration 33 === -------------------------------------- diff --git a/elenasrc3/common/common.h b/elenasrc3/common/common.h index 1ed33d50d..dfe006427 100644 --- a/elenasrc3/common/common.h +++ b/elenasrc3/common/common.h @@ -89,6 +89,7 @@ namespace elena_lang constexpr pos_t INVALID_POS = -1; constexpr ref_t INVALID_REF = -1; constexpr ref_t MAX_OFFSET = 0x7FFFFFFF; + constexpr ref_t MID_OFFSET = 0x3FFFFFFF; constexpr addr_t INVALID_ADDR = -1; constexpr size_t INVALID_SIZE = -1; diff --git a/elenasrc3/common/tree.h b/elenasrc3/common/tree.h index 21a9ac335..6c9351f38 100644 --- a/elenasrc3/common/tree.h +++ b/elenasrc3/common/tree.h @@ -148,6 +148,19 @@ namespace elena_lang } } + void insertChild(pos_t parent, pos_t child) + { + auto r = (NodeRecord*)_body.get(parent); + if (r->child == INVALID_POS) { + r->child = child; + } + else { + auto nw = (NodeRecord*)_body.get(child); + nw->next = r->child; + r->child = child; + } + } + pos_t readParent(pos_t position) { if (position == INVALID_POS) @@ -460,6 +473,13 @@ namespace elena_lang return Node::read(_tree, child); } + Node insertNode(Key key, ref_t argument = 0) + { + pos_t child = _tree->insertChild(_position, key, argument, INVALID_POS); + + return Node::read(_tree, child); + } + // inject a child node between the current one and its children Node injectNode(Key key, int argument = 0) { @@ -508,6 +528,16 @@ namespace elena_lang return child; } + pos_t insertChild(pos_t position, Key key, ref_t reference, pos_t strArgPosition) + { + NodeArg arg(reference, strArgPosition); + + pos_t child = newChild(position, key, arg); + + insertChild(position, child); + + return child; + } public: class Writer diff --git a/elenasrc3/elc/clicommon.h b/elenasrc3/elc/clicommon.h index 0df9cd33d..85839bcf6 100644 --- a/elenasrc3/elc/clicommon.h +++ b/elenasrc3/elc/clicommon.h @@ -4,6 +4,7 @@ // This file contains the compiler common interfaces & types // // (C)2021-2024, by Aleksey Rakov +// (C)2024, by ELENA-LANG Org //--------------------------------------------------------------------------- #ifndef CLICOMMON_H @@ -158,6 +159,13 @@ enum class Visibility Public = 4, }; +enum class SymbolKind +{ + Normal = 0, + Static = 1, + ThreadVar = 2 +}; + struct BranchingInfo { ref_t typeRef; @@ -194,7 +202,7 @@ struct BuiltinReferences mssg_t constructor_message; mssg_t protected_constructor_message; mssg_t invoke_message; - mssg_t init_message; + mssg_t init_message, static_init_message; mssg_t add_message, sub_message, mul_message, div_message; mssg_t band_message, bor_message, bxor_message; mssg_t and_message, or_message, xor_message; @@ -228,7 +236,7 @@ struct BuiltinReferences dispatch_message = constructor_message = 0; protected_constructor_message = 0; - invoke_message = init_message = 0; + invoke_message = init_message = static_init_message = 0; add_message = sub_message = mul_message = div_message = 0; band_message = bor_message = bxor_message = 0; and_message = or_message = xor_message = 0; @@ -429,6 +437,7 @@ enum class ExpressionAttribute : pos64_t LookaheadExprMode = 0x00080000000, Class = 0x00100000000, Nillable = 0x00200000000, + AllowGenericSignature= 0x00400000000, OutRefOp = 0x01000000000, WithVariadicArgCast = 0x02008000000, DistributedForward = 0x04000000000, @@ -493,6 +502,7 @@ struct FieldAttributes int size; bool isConstant; bool isStatic; + bool isThreadStatic; bool isEmbeddable; bool isReadonly; bool inlineArray; @@ -621,6 +631,13 @@ class ErrorProcessor : public ErrorProcessorBase _presenter->print(_presenter->getMessage(code), arg, arg2); } + void raiseError(int code) override + { + _presenter->print(_presenter->getMessage(code)); + + throw CLIException(); + } + void raiseError(int code, ustr_t arg) override { _presenter->print(_presenter->getMessage(code), arg); diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h index ec5141cf2..cc7cae194 100644 --- a/elenasrc3/elc/cliconst.h +++ b/elenasrc3/elc/cliconst.h @@ -13,7 +13,7 @@ namespace elena_lang { - #define ELC_REVISION_NUMBER 0x0030 + #define ELC_REVISION_NUMBER 0x003C #if defined _M_IX86 || _M_X64 @@ -28,8 +28,8 @@ namespace elena_lang #endif // --- Information messages --- - constexpr auto ELC_GREETING = "ELENA Command-line compiler %d.%d.%d (C)2005-2024 by Aleksey Rakov\n"; - constexpr auto ELC_STARTING = "Project: %s, Platform: %s, Target type: %s"; + constexpr auto ELC_GREETING = "ELENA Command-line compiler %d.%d.%d (C)2005-2024 by Aleksey Rakov, ELENA-LANG Org\n"; + constexpr auto ELC_STARTING = "\nProject: %s, Platform: %s, Target type: %s"; constexpr auto ELC_PROFILE_INFO = "Project profile: %s"; constexpr auto ELC_CLEANING = "Cleaning up"; constexpr auto ELC_LINKING = "Linking..\n"; @@ -50,9 +50,10 @@ namespace elena_lang constexpr auto ELC_PROFILE_WARNING = "\nWARNING - Please select one of available profiles:%s\n"; constexpr auto ELC_PRJ_COLLECTION_WARNING = "\nWARNING - The project collection must be the last argument:%s\n"; - constexpr auto ELC_HELP_INFO = "elena-cli {-key} {source-file+ | project-file}\nkeys:\n -f{fwd=reference} - add a forward\n -l{profile name} - selecct a profile\n -m - turning on address mapping output\n -o{0 | 1 | 2} - set the optimization level\n -p - set the base path\n -r - clean the compilation output\n -s{ stackReserv:n } - set the linker option - stack reserved\n -t{ template name } - load the project template\n -v - turn on a verbose output mode\n - w{ 0 | 1 | 2 | 3 } - set the minimal warnings level to X = { 0 | 1 | 2 | 3 }\n -xb[-] - turn on / off a conditional boxing\n -xe[-] - turn on / off a compile-time expression evaluation\n -xm[-] - turn on / off auto loading module extension list\n -xp[-] - turn on / off generation of the parameter meta info"; + constexpr auto ELC_HELP_INFO = "elena-cli {-key} {source-file+ | project-file}\nkeys:\n -el{5 | 6} - specifying grammar compatibility\n -f{fwd=reference} - add a forward\n -l{profile name} - selecct a profile\n -m - turning on address mapping output\n -o{0 | 1 | 2} - set the optimization level\n -p - set the base path\n -r - clean the compilation output\n -s{ stackReserv:n } - set the linker option - stack reserved\n -t{ template name } - load the project template\n -v - turn on a verbose output mode\n - w{ 0 | 1 | 2 | 3 } - set the minimal warnings level to X = { 0 | 1 | 2 | 3 }\n -xb[-] - turn on / off a conditional boxing\n -xe[-] - turn on / off a compile-time expression evaluation\n -xm[-] - turn on / off auto loading module extension list\n -xp[-] - turn on / off generation of the parameter meta info"; - constexpr auto SYNTAX_FILE = "syntax60.dat"; + constexpr auto SYNTAX50_FILE = "syntax50.dat"; + constexpr auto SYNTAX60_FILE = "syntax60.dat"; constexpr auto BC_RULES_FILE = "bc_rules60.dat"; constexpr auto BT_RULES_FILE = "bt_rules60.dat"; diff --git a/elenasrc3/elc/compiler.cpp b/elenasrc3/elc/compiler.cpp index 04335a1da..ec37be168 100644 --- a/elenasrc3/elc/compiler.cpp +++ b/elenasrc3/elc/compiler.cpp @@ -271,6 +271,7 @@ inline bool isSingleObject(ObjectKind kind) case ObjectKind::Constant: case ObjectKind::ConstArray: case ObjectKind::StaticField: + case ObjectKind::StaticThreadField: case ObjectKind::StaticConstField: case ObjectKind::ClassStaticConstField: case ObjectKind::LocalField: @@ -1152,7 +1153,7 @@ Compiler::SourceScope :: SourceScope(Scope* parent, ref_t reference, Visibility Compiler::SymbolScope :: SymbolScope(NamespaceScope* ns, ref_t reference, Visibility visibility) : SourceScope(ns, reference, visibility), info({}) { - isStatic = false; + type = SymbolKind::Normal; reserved1 = reserved2 = 0; reservedArgs = ns->moduleScope->minimalArgList; } @@ -1190,6 +1191,7 @@ Compiler::ClassScope :: ClassScope(Scope* ns, ref_t reference, Visibility visibi abstractMode = abstractBasedMode = false; extensionDispatcher = false; withPrivateField = false; + withStaticConstructor = false; } inline ObjectInfo mapClassInfoField(ClassInfo& info, ustr_t identifier, ExpressionAttribute attr, bool ignoreFields) @@ -1228,6 +1230,9 @@ inline ObjectInfo mapClassInfoField(ClassInfo& info, ustr_t identifier, Expressi }; } + else if (staticFieldInfo.offset == MID_OFFSET) { + return { ObjectKind::StaticThreadField, staticFieldInfo.typeInfo, staticFieldInfo.valueRef }; + } else return { ObjectKind::StaticField, staticFieldInfo.typeInfo, staticFieldInfo.valueRef }; } @@ -3191,8 +3196,12 @@ void Compiler :: generateClassStaticField(ClassScope& scope, SyntaxNode node, Fi node.setArgumentReference(staticRef); } + if (attrs.isThreadStatic) { + // NOTE : MID_OFFSET indicates the sealed thread static field + scope.info.statics.add(name, { MID_OFFSET, typeInfo, staticRef }); + } // NOTE : MAX_OFFSET indicates the sealed static field - scope.info.statics.add(name, { MAX_OFFSET, typeInfo, staticRef }); + else scope.info.statics.add(name, { MAX_OFFSET, typeInfo, staticRef }); } } @@ -3373,7 +3382,7 @@ void Compiler :: generateClassFields(ClassScope& scope, SyntaxNode node, bool si FieldAttributes attrs = {}; declareFieldAttributes(scope, current, attrs); - if ((attrs.isConstant && !isClassClassMode) || attrs.isStatic) { + if ((attrs.isConstant && !isClassClassMode) || attrs.isStatic || attrs.isThreadStatic) { generateClassStaticField(scope, current, attrs); } else if (!isClassClassMode) { @@ -3790,6 +3799,24 @@ void Compiler :: declareVMTMessage(MethodScope& scope, SyntaxNode node, bool wit } else scope.raiseError(errIllegalMethod, node); } + else if (scope.checkHint(MethodHint::Static) && scope.checkHint(MethodHint::Constructor) && unnamedMessage) { + if (paramCount > 0) + scope.raiseError(errInvalidOperation, node); + + ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class); + + // HOTFIX : it is a special type of constructor, so constructor hint must be removed + scope.info.hints &= ~(ref_t)MethodHint::Constructor; + + actionStr.copy(CLASS_INIT_MESSAGE); + unnamedMessage = false; + flags |= FUNCTION_MESSAGE; + flags |= STATIC_MESSAGE; + + node.parentNode().insertNode(SyntaxKey::HasStaticConstructor, 1); + + addStaticInitializerMethod(*classScope, node); + } else if (scope.checkHint(MethodHint::Constructor) && unnamedMessage) { actionStr.copy(CONSTRUCTOR_MESSAGE); unnamedMessage = false; @@ -4652,8 +4679,8 @@ void Compiler :: declareSymbolAttributes(SymbolScope& scope, SyntaxNode node, bo while (current != SyntaxKey::None) { switch (current.key) { case SyntaxKey::Attribute: - if (!_logic->validateSymbolAttribute(current.arg.value, scope.visibility, constant, scope.isStatic)) { - current.setArgumentValue(0); // HOTFIX : to prevent duplicate warnings + if (!_logic->validateSymbolAttribute(current.arg.value, scope.visibility, constant, scope.type)) { + current.setArgumentValue(0); // HOTFIX : to prevent duplicate warnings scope.raiseWarning(WARNING_LEVEL_1, wrnInvalidHint, current); } break; @@ -6367,10 +6394,8 @@ ExternalInfo Compiler :: mapExternal(Scope& scope, SyntaxNode node) return scope.moduleScope->mapExternal(dllAlias, functionName); } -ref_t Compiler :: compileStaticAssigning(ClassScope& scope, SyntaxNode node) +SyntaxNode Compiler :: addStaticInitializerMethod(ClassScope& scope, SyntaxNode node) { - ref_t actionRef = 0; - SyntaxNode rootNode = node.parentNode(); while (rootNode != SyntaxKey::Class) { rootNode = rootNode.parentNode(); @@ -6381,18 +6406,24 @@ ref_t Compiler :: compileStaticAssigning(ClassScope& scope, SyntaxNode node) IdentifierString sectionName(scope.module->resolveReference(scope.reference)); sectionName.append(INITIALIZER_SECTION); - actionRef = scope.moduleScope->mapAnonymous(*sectionName); + ref_t actionRef = scope.moduleScope->mapAnonymous(*sectionName); staticInitializer = rootNode.appendChild(SyntaxKey::StaticInitializerMethod, actionRef); scope.addAttribute(ClassAttribute::Initializer, actionRef); } - else actionRef = staticInitializer.arg.reference; + + return staticInitializer; +} + +ref_t Compiler :: compileStaticAssigning(ClassScope& scope, SyntaxNode node) +{ + SyntaxNode staticInitializer = addStaticInitializerMethod(scope, node); SyntaxTreeWriter writer(staticInitializer); SyntaxTree::copyNode(writer, node, true); - return actionRef; + return staticInitializer.arg.reference; } mssg_t Compiler :: resolveOperatorMessage(ModuleScopeBase* scope, int operatorId) @@ -7492,8 +7523,16 @@ void Compiler :: compileSymbol(BuildTreeWriter& writer, SymbolScope& scope, Synt writer.appendNode(BuildKey::Path, *ns->sourcePath); writer.newNode(BuildKey::Tape); - if (scope.isStatic) - writer.appendNode(BuildKey::OpenStatic, node.arg.reference); + switch (scope.type) { + case SymbolKind::Static: + writer.appendNode(BuildKey::OpenStatic, node.arg.reference); + break; + case SymbolKind::ThreadVar: + writer.appendNode(BuildKey::OpenThreadVar, node.arg.reference); + break; + default: + break; + } writer.appendNode(BuildKey::OpenFrame); @@ -7508,8 +7547,16 @@ void Compiler :: compileSymbol(BuildTreeWriter& writer, SymbolScope& scope, Synt writer.appendNode(BuildKey::CloseFrame); - if (scope.isStatic) - writer.appendNode(BuildKey::CloseStatic, node.arg.reference); + switch (scope.type) { + case SymbolKind::Static: + writer.appendNode(BuildKey::CloseStatic, node.arg.reference); + break; + case SymbolKind::ThreadVar: + writer.appendNode(BuildKey::CloseThreadVar, node.arg.reference); + break; + default: + break; + } writer.appendNode(BuildKey::Exit); @@ -7948,10 +7995,23 @@ void Compiler :: compileStaticInitializerMethod(BuildTreeWriter& writer, ClassSc current = current.nextNode(); } + // call the static constructor if available + if (scope.withStaticConstructor) { + Expression expression(this, scope, nestedWriter); + + ArgumentsInfo args; + + MessageResolution resolution = { true, scope.moduleScope->buildins.static_init_message }; + + expression.compileMessageOperation(node, mapClassSymbol(scope, scope.reference), resolution, + 0, args, EAttr::None, nullptr); + } + nestedWriter.appendNode(BuildKey::CloseFrame); nestedWriter.appendNode(BuildKey::Exit); nestedWriter.closeNode(); + saveFrameAttributes(nestedWriter, scope, scope.moduleScope->minimalArgList, 0); nestedWriter.closeNode(); } @@ -8043,7 +8103,7 @@ ObjectInfo Compiler :: compileRedirect(BuildTreeWriter& writer, CodeScope& codeS signRef, arguments, EAttr::None, &updatedOuterArgs); if (outputRef) { - expression.convertObject(node, expression.saveToTempLocal(retVal), outputRef, true, false, false); + expression.convertObject(node, expression.saveToTempLocal(retVal), outputRef, true, false, false, false); } expression.scope.syncStack(); @@ -9458,6 +9518,9 @@ void Compiler :: compileVMT(BuildTreeWriter& writer, ClassScope& scope, SyntaxNo SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { switch (current.key) { + case SyntaxKey::HasStaticConstructor: + scope.withStaticConstructor = true; + break; case SyntaxKey::Method: { if (exclusiveMode @@ -9812,7 +9875,13 @@ void Compiler :: compileNamespace(BuildTreeWriter& writer, NamespaceScope& ns, S case SyntaxKey::Symbol: { SymbolScope symbolScope(&ns, current.arg.reference, ns.defaultVisibility); - symbolScope.isStatic = SyntaxTree::ifChildExists(current, SyntaxKey::Attribute, V_STATIC); + if (SyntaxTree::ifChildExists(current, SyntaxKey::Attribute, V_STATIC)) { + symbolScope.type = SymbolKind::Static; + } + else if (SyntaxTree::ifChildExists(current, SyntaxKey::Attribute, V_THREADVAR)) { + symbolScope.type = SymbolKind::ThreadVar; + } + symbolScope.visibility = ns.moduleScope->retrieveVisibility(symbolScope.reference); compileSymbol(writer, symbolScope, current); @@ -9965,6 +10034,9 @@ void Compiler :: prepare(ModuleScopeBase* moduleScope, ForwardResolverBase* forw moduleScope->buildins.init_message = encodeMessage(moduleScope->module->mapAction(INIT_MESSAGE, 0, false), 1, STATIC_MESSAGE); + moduleScope->buildins.static_init_message = + encodeMessage(moduleScope->module->mapAction(CLASS_INIT_MESSAGE, 0, false), + 0, STATIC_MESSAGE | FUNCTION_MESSAGE); moduleScope->buildins.invoke_message = encodeMessage( moduleScope->module->mapAction(INVOKE_MESSAGE, 0, false), 1, FUNCTION_MESSAGE); moduleScope->buildins.add_message = @@ -10404,14 +10476,22 @@ void Compiler :: injectVirtualMultimethod(SyntaxNode classNode, SyntaxKey method // try to resolve an argument list in run-time if it is only a single dispatch and argument list is not weak // !! temporally do not support variadic arguments - if (isSingleDispatch(classNode, methodType, message, resendMessage) && - injectVirtualStrongTypedMultimethod(classNode, methodType, scope, message, resendMessage, - outputInfo, visibility, isExtension, nillableArgs)) - { - // mark the message as a signle dispatcher if the class is sealed / closed / class class - // and default multi-method was not explicitly declared - if (testany(info.header.flags, elClosed | elClassClass) && !inherited) + if (isSingleDispatch(classNode, methodType, message, resendMessage)) { + if (injectVirtualStrongTypedMultimethod(classNode, methodType, scope, message, resendMessage, + outputInfo, visibility, isExtension, nillableArgs)) + { + // mark the message as a signle dispatcher if the class is sealed / closed / class class + // and default multi-method was not explicitly declared + if (testany(info.header.flags, elClosed | elClassClass) && !inherited) + info.attributes.add({ message, ClassAttribute::SingleDispatch }, resendMessage); + } + else if (actionRef) { + // if it is a generic single dispatch + injectVirtualMultimethod(classNode, methodType, scope, message, resendMessage, resendTarget, + outputInfo, visibility, isExtension); + info.attributes.add({ message, ClassAttribute::SingleDispatch }, resendMessage); + } } else { if (inherited) { @@ -10604,9 +10684,11 @@ inline void injectParameters(Compiler::Scope& scope, SyntaxNode methodNode, ref_ } } else { + pos_t startIndex = test(message, FUNCTION_MESSAGE) ? 0 : 1; + pos_t len = getArgCount(message); String arg; - for (pos_t i = 1; i < len; i++) { + for (pos_t i = startIndex; i < len; i++) { arg.copy("$"); arg.appendInt(i); @@ -10619,9 +10701,11 @@ inline void injectParameters(Compiler::Scope& scope, SyntaxNode methodNode, ref_ inline void injectArguments(Compiler::Scope& scope, SyntaxNode opNode, mssg_t message) { + pos_t startIndex = test(message, FUNCTION_MESSAGE) ? 0 : 1; + pos_t len = getArgCount(message); String arg; - for (pos_t i = 1; i < len; i++) { + for (pos_t i = startIndex; i < len; i++) { arg.copy("$"); arg.appendInt(i); @@ -10629,7 +10713,7 @@ inline void injectArguments(Compiler::Scope& scope, SyntaxNode opNode, mssg_t me } } -void Compiler :: injectMethodInvoker(Scope& scope, SyntaxNode classNode, mssg_t message, ustr_t targetArg) +void Compiler :: injectMethodInvoker(Scope& scope, SyntaxNode classNode, mssg_t message, SyntaxKey targetKey, ustr_t targetArg) { SyntaxNode methodNode = classNode.appendChild(SyntaxKey::ClosureBlock); @@ -10641,7 +10725,7 @@ void Compiler :: injectMethodInvoker(Scope& scope, SyntaxNode classNode, mssg_t SyntaxNode body = methodNode.appendChild(SyntaxKey::ReturnExpression).appendChild(SyntaxKey::Expression); SyntaxNode opNode = body.appendChild(((message & PREFIX_MESSAGE_MASK) == PROPERTY_MESSAGE) ? SyntaxKey::PropertyOperation : SyntaxKey::MessageOperation); - opNode.appendChild(SyntaxKey::Object).appendChild(SyntaxKey::identifier, targetArg); + opNode.appendChild(SyntaxKey::Object).appendChild(targetKey, targetArg); opNode.appendChild(SyntaxKey::Message, message); injectArguments(scope, opNode, message); @@ -11765,6 +11849,7 @@ ObjectInfo Compiler::Expression :: compileMessageOperationR(SyntaxNode node, Syn paramMode = paramMode | EAttr::WithVariadicArg; } } + else paramMode = paramMode | EAttr::AllowGenericSignature; } ref_t expectedSignRef = 0; @@ -12459,6 +12544,20 @@ ObjectInfo Compiler::Expression :: compileAltOperation(SyntaxNode node) return { ObjectKind::Object }; } +bool Compiler :: checkifSingleObject(Scope& scope, SyntaxNode loperand) +{ + if (loperand == SyntaxKey::Expression) + loperand = loperand.firstChild(); + + if (loperand == SyntaxKey::Object) { + ObjectInfo info = mapObject(scope, loperand, EAttr::None); + + return isSingleObject(info.kind); + } + + return false; +} + ObjectInfo Compiler::Expression :: compileIsNilOperation(SyntaxNode node) { ObjectInfo ehLocal = declareTempStructure({ (int)scope.moduleScope->ehTableEntrySize, false }); @@ -12505,13 +12604,31 @@ ObjectInfo Compiler::Expression :: compileIsNilOperation(SyntaxNode node) loperand = saveToTempLocal({ ObjectKind::Object }); } + ObjectInfo roperand = {}; + SyntaxNode altNode = current.nextNode(SyntaxKey::DeclarationMask); - ObjectInfo roperand = compile(altNode, 0, EAttr::Parameter, nullptr); + // if non-branching operation is possible + if (compiler->checkifSingleObject(scope, altNode)) { + // COALESCE operation is used + roperand = compile(altNode, 0, EAttr::Parameter, nullptr); - writeObjectInfo(roperand, node); - writer->appendNode(BuildKey::SavingInStack); - writeObjectInfo(loperand, node); - writer->appendNode(BuildKey::NilOp, ISNIL_OPERATOR_ID); + writeObjectInfo(roperand, node); + writer->appendNode(BuildKey::SavingInStack); + writeObjectInfo(loperand, node); + writer->appendNode(BuildKey::NilOp, ISNIL_OPERATOR_ID); + } + else { + writer->newNode(BuildKey::ShortCircuitOp, ISNIL_OPERATOR_ID); + + writer->newNode(BuildKey::Tape); + writeObjectInfo(loperand, node); + writer->closeNode(); + writer->newNode(BuildKey::Tape); + roperand = compile(altNode, 0, EAttr::Parameter, nullptr); + writer->closeNode(); + + writer->closeNode(); + } // make the expression strong-typed if the both arguments are of the same type TypeInfo typeInfo = {}; @@ -12747,6 +12864,24 @@ ObjectInfo Compiler::Expression :: compileClosureOperation(SyntaxNode node) } } + ustr_t targetArg = nullptr; + SyntaxKey targetKey = SyntaxKey::None; + + if (!targetMessage) { + ObjectInfo function = scope.mapIdentifier(methodName, false, EAttr::None); + if (function.kind == ObjectKind::Singleton) { + targetArg = methodName; + targetKey = SyntaxKey::identifier; + + int dummy = 0; + targetMessage = compiler->_logic->resolveFunctionSingleDispatch(*scope.moduleScope, function.reference, dummy); + } + } + else { + targetArg = *scope.moduleScope->selfVar; + targetKey = SyntaxKey::identifier; + } + if (!targetMessage) scope.raiseError(errInvalidOperation, node); @@ -12757,7 +12892,7 @@ ObjectInfo Compiler::Expression :: compileClosureOperation(SyntaxNode node) classWriter.newNode(SyntaxKey::Root); SyntaxNode rootNode = classWriter.CurrentNode(); - compiler->injectMethodInvoker(scope, rootNode, targetMessage, *scope.moduleScope->selfVar); + compiler->injectMethodInvoker(scope, rootNode, targetMessage, targetKey, targetArg); classWriter.closeNode(); @@ -12896,7 +13031,7 @@ ObjectInfo Compiler::Expression :: validateObject(SyntaxNode node, ObjectInfo re return retVal; } - retVal = convertObject(node, retVal, targetRef, dynamicRequired, false, nillable); + retVal = convertObject(node, retVal, targetRef, dynamicRequired, false, nillable, false); if (paramMode && hasToBePresaved(retVal)) retVal = saveToTempLocal(retVal); } @@ -12962,6 +13097,7 @@ ref_t Compiler::Expression :: compileMessageArguments(SyntaxNode current, Argume ArgumentsInfo* updatedOuterArgs, ArgumentListType& argListType, int nillableArgs) { bool variadicArg = EAttrs::testAndExclude(mode, EAttr::WithVariadicArg); + bool allowGenericSignature = EAttrs::testAndExclude(mode, EAttr::AllowGenericSignature); EAttr paramMode = EAttr::Parameter | EAttr::RetValExpected; if (EAttrs::testAndExclude(mode, EAttr::NoPrimitives)) @@ -13023,7 +13159,7 @@ ref_t Compiler::Expression :: compileMessageArguments(SyntaxNode current, Argume if (signatureLen > 0 && signatureLen <= ARG_COUNT) { bool anonymous = true; for (ref_t i = 0; i < signatureLen; i++) { - if (signatures[i] != superReference) { + if (signatures[i] != superReference || allowGenericSignature) { anonymous = false; break; } @@ -13229,7 +13365,7 @@ ObjectInfo Compiler::Expression :: compileNewArrayOp(SyntaxNode node, ObjectInfo NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); auto conversionRoutine = compiler->_logic->retrieveConversionRoutine(compiler, *scope.moduleScope, *nsScope->nsName, - targetRef, source.typeInfo); + targetRef, source.typeInfo, false); if (conversionRoutine.result == ConversionResult::BoxingRequired) { source.typeInfo = { targetRef }; } @@ -13265,7 +13401,7 @@ ObjectInfo Compiler::Expression :: compileNewArrayOp(SyntaxNode node, ObjectInfo } ObjectInfo Compiler::Expression :: convertObject(SyntaxNode node, ObjectInfo source, - ref_t targetRef, bool dynamicRequired, bool withoutBoxing, bool nillable) + ref_t targetRef, bool dynamicRequired, bool withoutBoxing, bool nillable, bool directConversion) { if (!compiler->_logic->isCompatible(*scope.moduleScope, { targetRef }, source.typeInfo, false)) { if (source.kind == ObjectKind::Default) { @@ -13299,7 +13435,7 @@ ObjectInfo Compiler::Expression :: convertObject(SyntaxNode node, ObjectInfo sou NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); auto conversionRoutine = compiler->_logic->retrieveConversionRoutine(compiler, *scope.moduleScope, *nsScope->nsName, - targetRef, source.typeInfo); + targetRef, source.typeInfo, directConversion); if (!withoutBoxing && conversionRoutine.result == ConversionResult::BoxingRequired) { // if it is implcitily compatible switch (source.kind) { @@ -13906,6 +14042,9 @@ bool Compiler::Expression :: writeObjectInfo(ObjectInfo info, bool allowMeta) case ObjectKind::StaticField: writer->appendNode(BuildKey::StaticVar, info.reference); break; + case ObjectKind::StaticThreadField: + writer->appendNode(BuildKey::ThreadVar, info.reference); + break; case ObjectKind::ByRefParam: case ObjectKind::OutParam: writeObjectInfo({ ObjectKind::Param, info.typeInfo, info.reference }); @@ -13940,6 +14079,7 @@ ObjectInfo Compiler::Expression :: boxArgumentLocally(ObjectInfo info, case ObjectKind::Outer: case ObjectKind::OuterField: case ObjectKind::StaticField: + case ObjectKind::StaticThreadField: if (forced) { return boxLocally(info, stackSafe); } @@ -14151,6 +14291,11 @@ bool Compiler::Expression :: compileAssigningOp(ObjectInfo target, ObjectInfo ex operationType = BuildKey::StaticAssigning; operand = target.reference; break; + case ObjectKind::StaticThreadField: + scope.markAsAssigned(target); + operationType = BuildKey::ThreadVarAssigning; + operand = target.reference; + break; case ObjectKind::FieldAddress: scope.markAsAssigned(target); fieldMode = true; @@ -14446,7 +14591,7 @@ ObjectInfo Compiler::Expression :: compileMessageOperationR(ObjectInfo target, S return arguments[0]; } - else return convertObject(messageNode, arguments[0], targetRef, false, true, false); + else return convertObject(messageNode, arguments[0], targetRef, false, true, false, true); } else scope.raiseError(errInvalidOperation, messageNode); break; @@ -15097,6 +15242,10 @@ ObjectInfo Compiler::Expression :: boxLocally(ObjectInfo info, bool stackSafe) writer->appendNode(BuildKey::StaticVar, info.reference); writer->newNode(BuildKey::CopyingAccField, 0); break; + case ObjectKind::StaticThreadField: + writer->appendNode(BuildKey::ThreadVar, info.reference); + writer->newNode(BuildKey::CopyingAccField, 0); + break; default: writer->appendNode(BuildKey::Field, info.reference); writer->newNode(BuildKey::CopyingAccField, 0); @@ -15389,7 +15538,7 @@ ObjectInfo Compiler::Expression :: boxVariadicArgument(ObjectInfo info) if (info.typeInfo.typeRef && info.typeInfo.typeRef != typeRef) { // if the conversion is required ObjectInfo convInfo = convertObject({}, destLocal, - info.typeInfo.typeRef, false, false, false); + info.typeInfo.typeRef, false, false, false, false); compileAssigningOp(destLocal, convInfo, dummy); @@ -15403,7 +15552,7 @@ void Compiler::Expression :: compileAssigning(SyntaxNode node, ObjectInfo target { if (!noConversion) { source = convertObject(node, source, - compiler->resolveStrongType(scope, target.typeInfo), false, false, false); + compiler->resolveStrongType(scope, target.typeInfo), false, false, false, false); } bool nillableOp = false; @@ -15417,7 +15566,7 @@ void Compiler::Expression :: compileAssigning(SyntaxNode node, ObjectInfo target void Compiler::Expression :: compileConverting(SyntaxNode node, ObjectInfo source, ref_t targetRef, bool stackSafe) { if (targetRef && targetRef != V_AUTO) { - source = convertObject(node, source, targetRef, false, false, false); + source = convertObject(node, source, targetRef, false, false, false, false); scope.syncStack(); } diff --git a/elenasrc3/elc/compiler.h b/elenasrc3/elc/compiler.h index 80f84f684..54d2c30da 100644 --- a/elenasrc3/elc/compiler.h +++ b/elenasrc3/elc/compiler.h @@ -90,6 +90,7 @@ namespace elena_lang MethodName, FieldName, StaticField, + StaticThreadField, StaticConstField, ClassStaticConstField, Wrapper, @@ -586,7 +587,7 @@ namespace elena_lang struct SymbolScope : SourceScope { SymbolInfo info; - bool isStatic; + SymbolKind type; pos_t reserved1; // defines managed frame size pos_t reserved2; // defines unmanaged frame size (excluded from GC frame chain) @@ -623,6 +624,7 @@ namespace elena_lang bool abstractBasedMode; bool extensionDispatcher; bool withPrivateField; + bool withStaticConstructor; Scope* getScope(ScopeLevel level) override { @@ -1299,7 +1301,7 @@ namespace elena_lang ObjectInfo compileNewArrayOp(SyntaxNode node, ObjectInfo source, ref_t targetRef, ArgumentsInfo& arguments); ObjectInfo convertObject(SyntaxNode node, ObjectInfo source, ref_t targetRef, bool dynamicRequired, - bool withoutBoxing, bool nillable); + bool withoutBoxing, bool nillable, bool directConversion); ObjectInfo compileMessageOperation(SyntaxNode node, ObjectInfo target, MessageResolution resolution, ref_t implicitSignatureRef, ArgumentsInfo& arguments, ExpressionAttributes mode, ArgumentsInfo* updatedOuterArgs); @@ -1453,6 +1455,8 @@ namespace elena_lang TypeAttributes& attributes, bool declarationMode, bool objectMode); void declareIncludeAttributes(Scope& scope, SyntaxNode node, bool& textBlock); + bool checkifSingleObject(Scope& scope, SyntaxNode node); + static int defineFieldSize(Scope& scope, ObjectInfo info); ObjectInfo defineArrayType(Scope& scope, ObjectInfo info, bool declarationMode); @@ -1738,6 +1742,7 @@ namespace elena_lang void compileNamespace(BuildTreeWriter& writer, NamespaceScope& ns, SyntaxNode node); + static SyntaxNode addStaticInitializerMethod(ClassScope& scope, SyntaxNode node); ref_t compileStaticAssigning(ClassScope& scope, SyntaxNode node); void recreateFieldType(ClassScope& scope, SyntaxNode node, ustr_t fieldName); @@ -1780,7 +1785,7 @@ namespace elena_lang void injectInterfaceDispatch(Scope& scope, SyntaxNode node, ref_t parentRef); void injectVirtualDispatchMethod(Scope& scope, SyntaxNode classNode, mssg_t message, ref_t outputRef, SyntaxKey key, ustr_t arg); - void injectMethodInvoker(Scope& scope, SyntaxNode classNode, mssg_t message, ustr_t targetArg); + void injectMethodInvoker(Scope& scope, SyntaxNode classNode, mssg_t message, SyntaxKey targetKey, ustr_t targetArg); void injectStrongRedirectMethod(Scope& scope, SyntaxNode node, SyntaxKey methodType, ref_t reference, mssg_t message, mssg_t redirectMessage, TypeInfo outputInfo); diff --git a/elenasrc3/elc/compilerlogic.cpp b/elenasrc3/elc/compilerlogic.cpp index af989ed55..8906162e1 100644 --- a/elenasrc3/elc/compilerlogic.cpp +++ b/elenasrc3/elc/compilerlogic.cpp @@ -4,6 +4,7 @@ // This file contains ELENA compiler logic class implementation. // // (C)2021-2024, by Aleksey Rakov +// (C)2024, by ELENA-LANG Org //--------------------------------------------------------------------------- #include "elena.h" @@ -783,12 +784,15 @@ bool CompilerLogic :: validateTemplateAttribute(ref_t attribute, Visibility& vis return true; } -bool CompilerLogic :: validateSymbolAttribute(ref_t attribute, Visibility& visibility, bool& constant, bool& isStatic) +bool CompilerLogic :: validateSymbolAttribute(ref_t attribute, Visibility& visibility, bool& constant, SymbolKind& symbolKind) { switch (attribute) { case V_PUBLIC: visibility = Visibility::Public; break; + case V_INTERNAL: + visibility = Visibility::Internal; + break; case V_PRIVATE: visibility = Visibility::Private; break; @@ -798,7 +802,13 @@ bool CompilerLogic :: validateSymbolAttribute(ref_t attribute, Visibility& visib constant = true; break; case V_STATIC: - isStatic = true; + symbolKind = SymbolKind::Static; + break; + case V_THREADVAR: + symbolKind = SymbolKind::ThreadVar; + break; + case 0: + // ignore idle break; default: return false; @@ -898,6 +908,9 @@ bool CompilerLogic :: validateFieldAttribute(ref_t attribute, FieldAttributes& a case V_STATIC: attrs.isStatic = true; break; + case V_THREADVAR: + attrs.isThreadStatic = true; + break; case V_READONLY: attrs.isReadonly = true; break; @@ -1307,11 +1320,11 @@ bool CompilerLogic :: isReadOnly(ClassInfo& info) bool CompilerLogic :: isEmbeddableArray(ModuleScopeBase& scope, ref_t reference) { if (scope.cachedEmbeddableArrays.exist(reference)) - return scope.cachedEmbeddableArrays.get(reference); + return scope.cachedEmbeddableArrays.get(reference); ClassInfo info; if (defineClassInfo(scope, info, reference, true)) { - auto retVal = isEmbeddableArray(info); + auto retVal = isEmbeddableArray(info); scope.cachedEmbeddableArrays.add(reference, retVal); @@ -2274,7 +2287,7 @@ mssg_t CompilerLogic :: retrieveImplicitConstructor(ModuleScopeBase& scope, ref_ } ConversionRoutine CompilerLogic :: retrieveConversionRoutine(CompilerBase* compiler, ModuleScopeBase& scope, ustr_t ns, - ref_t targetRef, TypeInfo sourceInfo) + ref_t targetRef, TypeInfo sourceInfo, bool directConversion) { ClassInfo info; if (!defineClassInfo(scope, info, targetRef)) @@ -2325,7 +2338,7 @@ ConversionRoutine CompilerLogic :: retrieveConversionRoutine(CompilerBase* compi } // if there is a implicit conversion routine - if (!isPrimitiveRef(targetRef)) { + if (!isPrimitiveRef(targetRef) && !directConversion) { ref_t sourceRef = sourceInfo.isPrimitive() ? compiler->resolvePrimitiveType(scope, sourceInfo) : sourceInfo.typeRef; ref_t signRef = scope.module->mapSignature(&sourceRef, 1, false); @@ -2630,6 +2643,24 @@ mssg_t CompilerLogic :: resolveSingleDispatch(ModuleScopeBase& scope, ref_t refe else return 0; } +mssg_t CompilerLogic :: resolveFunctionSingleDispatch(ModuleScopeBase& scope, ref_t reference, int& nillableArgs) +{ + if (!reference) + return 0; + + ClassInfo info; + if (defineClassInfo(scope, info, reference)) { + ref_t actionRef = scope.module->mapAction(INVOKE_MESSAGE, 0, true); + for (int i = 0; i < ARG_COUNT; i++) { + mssg_t weakMessage = encodeMessage(actionRef, i, FUNCTION_MESSAGE); + + if (info.methods.exist(weakMessage)) + return weakMessage; + } + } + return 0; +} + inline size_t readSignatureMember(ustr_t signature, size_t index) { int level = 0; diff --git a/elenasrc3/elc/compilerlogic.h b/elenasrc3/elc/compilerlogic.h index a5144924b..9808f006f 100644 --- a/elenasrc3/elc/compilerlogic.h +++ b/elenasrc3/elc/compilerlogic.h @@ -98,7 +98,7 @@ namespace elena_lang ref_t definePrimitiveArray(ModuleScopeBase& scope, ref_t elementRef, bool structOne); bool validateTemplateAttribute(ref_t attribute, Visibility& visibility, TemplateType& type); - bool validateSymbolAttribute(ref_t attribute, Visibility& visibility, bool& constant, bool& isStatic); + bool validateSymbolAttribute(ref_t attribute, Visibility& visibility, bool& constant, SymbolKind& symbolKind); bool validateClassAttribute(ref_t attribute, ref_t& flags, Visibility& visibility); bool validateFieldAttribute(ref_t attribute, FieldAttributes& attrs); bool validateMethodAttribute(ref_t attribute, ref_t& hint, bool& explicitMode); @@ -184,7 +184,7 @@ namespace elena_lang mssg_t retrieveDynamicConvertor(ModuleScopeBase& scope, ref_t targetRef); ConversionRoutine retrieveConversionRoutine(CompilerBase* compiler, ModuleScopeBase& scope, ustr_t ns, - ref_t targetRef, TypeInfo sourceInfo); + ref_t targetRef, TypeInfo sourceInfo, bool directConversion); bool checkMethod(ClassInfo& info, mssg_t message, CheckMethodResult& result); bool checkMethod(ModuleScopeBase& scope, ref_t reference, mssg_t message, CheckMethodResult& result); @@ -197,6 +197,7 @@ namespace elena_lang CheckMethodResult& result); mssg_t resolveSingleDispatch(ModuleScopeBase& scope, ref_t reference, ref_t weakMessage, int& nillableArgs); + mssg_t resolveFunctionSingleDispatch(ModuleScopeBase& scope, ref_t reference, int& nillableArgs); void injectOverloadList(CompilerBase* compiler, ModuleScopeBase& scope, ClassInfo& info, ref_t classRef); void injectMethodOverloadList(CompilerBase* compiler, ModuleScopeBase& scope, ref_t flags, diff --git a/elenasrc3/elc/compiling.cpp b/elenasrc3/elc/compiling.cpp index 2504b7865..0c9ab3d36 100644 --- a/elenasrc3/elc/compiling.cpp +++ b/elenasrc3/elc/compiling.cpp @@ -317,7 +317,7 @@ ref_t CompilingProcess::TemplateGenerator :: generateClassTemplate(ModuleScopeBa // --- CompilingProcess --- -CompilingProcess :: CompilingProcess(PathString& appPath, path_t exeExtension, +CompilingProcess :: CompilingProcess(path_t appPath, path_t exeExtension, path_t modulePrologName, path_t prologName, path_t epilogName, PresenterBase* presenter, ErrorProcessor* errorProcessor, pos_t codeAlignment, @@ -325,7 +325,8 @@ CompilingProcess :: CompilingProcess(PathString& appPath, path_t exeExtension, JITCompilerBase* (*compilerFactory)(LibraryLoaderBase*, PlatformType) ) : _templateGenerator(this), - _forwards(nullptr) + _forwards(nullptr), + _appPath(appPath) { _exeExtension = exeExtension; _modulePrologName = modulePrologName; @@ -338,45 +339,19 @@ CompilingProcess :: CompilingProcess(PathString& appPath, path_t exeExtension, _codeAlignment = codeAlignment; _defaultCoreSettings = defaultCoreSettings; - PathString syntaxPath(*appPath, SYNTAX_FILE); - FileReader syntax(*syntaxPath, FileRBMode, FileEncoding::Raw, false); - if (syntax.isOpen()) { - TerminalMap terminals( - SyntaxTree::toParseKey(SyntaxKey::eof), - SyntaxTree::toParseKey(SyntaxKey::identifier), - SyntaxTree::toParseKey(SyntaxKey::reference), - SyntaxTree::toParseKey(SyntaxKey::globalreference), - SyntaxTree::toParseKey(SyntaxKey::string), - SyntaxTree::toParseKey(SyntaxKey::character), - SyntaxTree::toParseKey(SyntaxKey::wide), - SyntaxTree::toParseKey(SyntaxKey::integer), - SyntaxTree::toParseKey(SyntaxKey::hexinteger), - SyntaxTree::toParseKey(SyntaxKey::longinteger), - SyntaxTree::toParseKey(SyntaxKey::real), - SyntaxTree::toParseKey(SyntaxKey::constant), - SyntaxTree::toParseKey(SyntaxKey::interpolate)); - - _parser = new Parser(&syntax, terminals, _presenter); - _compiler = new Compiler( - _presenter, - _errorProcessor, - &_templateGenerator, - CompilerLogic::getInstance()); - } - else { - _errorProcessor->raisePathWarning(wrnSyntaxFileNotFound, *syntaxPath); + _compiler = new Compiler( + _presenter, + _errorProcessor, + &_templateGenerator, + CompilerLogic::getInstance()); - _parser = nullptr; - _compiler = nullptr; - } - - PathString bcRulesPath(*appPath, BC_RULES_FILE); + PathString bcRulesPath(appPath, BC_RULES_FILE); FileReader bcRuleReader(*bcRulesPath, FileRBMode, FileEncoding::Raw, false); if (bcRuleReader.isOpen()) { _bcRules.load(bcRuleReader, bcRuleReader.length()); } - PathString btRulesPath(*appPath, BT_RULES_FILE); + PathString btRulesPath(appPath, BT_RULES_FILE); FileReader btRuleReader(*btRulesPath, FileRBMode, FileEncoding::Raw, false); if (btRuleReader.isOpen()) { _btRules.load(btRuleReader, btRuleReader.length()); @@ -605,6 +580,35 @@ bool CompilingProcess :: buildModule(ProjectEnvironment& env, return buildSyntaxTree(moduleScope, syntaxTree, false, nullptr); } +void CompilingProcess :: configurateParser(SyntaxVersion version) +{ + PathString syntaxPath(_appPath, version == SyntaxVersion::L5 ? SYNTAX50_FILE : SYNTAX60_FILE); + FileReader syntax(*syntaxPath, FileRBMode, FileEncoding::Raw, false); + if (syntax.isOpen()) { + TerminalMap terminals( + SyntaxTree::toParseKey(SyntaxKey::eof), + SyntaxTree::toParseKey(SyntaxKey::identifier), + SyntaxTree::toParseKey(SyntaxKey::reference), + SyntaxTree::toParseKey(SyntaxKey::globalreference), + SyntaxTree::toParseKey(SyntaxKey::string), + SyntaxTree::toParseKey(SyntaxKey::character), + SyntaxTree::toParseKey(SyntaxKey::wide), + SyntaxTree::toParseKey(SyntaxKey::integer), + SyntaxTree::toParseKey(SyntaxKey::hexinteger), + SyntaxTree::toParseKey(SyntaxKey::longinteger), + SyntaxTree::toParseKey(SyntaxKey::real), + SyntaxTree::toParseKey(SyntaxKey::constant), + SyntaxTree::toParseKey(SyntaxKey::interpolate)); + + _parser = new Parser(&syntax, terminals, _presenter); + } + else { + _errorProcessor->raisePathWarning(wrnSyntaxFileNotFound, *syntaxPath); + + _parser = nullptr; + } +} + void CompilingProcess :: configurate(Project& project) { project.prepare(); @@ -713,6 +717,13 @@ void CompilingProcess :: link(Project& project, LinkerBase& linker, bool withTLS TargetImage code(project.SystemTarget(), &project, &_libraryProvider, _jitCompilerFactory, imageInfo, addressMapper); + // HOTFIX : TLS variable can be used only for MTA + if (!withTLS && code.getTLSSection()->length() > 0) { + _errorProcessor->raiseError(errTLSIsNotAllowed); + + return; + } + auto result = linker.run(project, code, uiType, _exeExtension); _presenter->print(ELC_SUCCESSFUL_LINKING); @@ -783,6 +794,7 @@ int CompilingProcess :: build(Project& project, { try { + configurateParser(project.getSyntaxVersion()); configurate(project); PlatformType targetType = project.TargetType(); diff --git a/elenasrc3/elc/compiling.h b/elenasrc3/elc/compiling.h index a9f3c5be3..d6f283476 100644 --- a/elenasrc3/elc/compiling.h +++ b/elenasrc3/elc/compiling.h @@ -68,6 +68,8 @@ namespace elena_lang TemplateGenerator(CompilingProcess* process); }; + path_t _appPath; + path_t _modulePrologName, _prologName, _epilogName; path_t _exeExtension; @@ -120,6 +122,8 @@ namespace elena_lang int minimalArgList, int ptrSize); + void configurateParser(SyntaxVersion version); + void configurate(Project& project); void cleanUp(ProjectBase& project); void compile(ProjectBase& project, @@ -151,7 +155,7 @@ namespace elena_lang _compiler->setVerboseOn(); } - CompilingProcess(PathString& appPath, path_t exeExtension, + CompilingProcess(path_t appPath, path_t exeExtension, path_t modulePrologName, path_t prologName, path_t epilogName, PresenterBase* presenter, ErrorProcessor* errorProcessor, pos_t codeAlignment, diff --git a/elenasrc3/elc/derivation.cpp b/elenasrc3/elc/derivation.cpp index 8950b3786..ba56fe19a 100644 --- a/elenasrc3/elc/derivation.cpp +++ b/elenasrc3/elc/derivation.cpp @@ -1735,6 +1735,7 @@ void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode flushInlineTemplate(writer, scope, node); break; case SyntaxKey::Declaration: + case SyntaxKey::None: scope.type = defineTemplateType(writer.CurrentNode()); if (scope.type == ScopeType::ExtensionTemplate) { diff --git a/elenasrc3/elc/errors.h b/elenasrc3/elc/errors.h index cd7184cef..05f996631 100644 --- a/elenasrc3/elc/errors.h +++ b/elenasrc3/elc/errors.h @@ -74,6 +74,7 @@ namespace elena_lang constexpr auto errMsgInvalidFile = "\nlinker: error 205: Invalid file '%s'\n"; constexpr auto errMsgInvalidParserTarget = "\nlinker: error 206: Invalid parser target '%s'\n"; constexpr auto errMsgInvalidParserTargetType = "\nlinker: error 207: Invalid parser target type '%s'\n"; + constexpr auto errMsgTLSIsNotAllowed = "\nlinker: error 208: thread variable can be used only for MTA\n"; constexpr auto errMsgInvalidModuleVersion = "\nlinker: error 210: Obsolete module file '%s'\n"; constexpr auto errMsgEmptyTarget = "\nlinker: error 212: Target is not specified\n"; diff --git a/elenasrc3/elc/linux/elc.cpp b/elenasrc3/elc/linux/elc.cpp index 3f134f414..df6f5d1da 100644 --- a/elenasrc3/elc/linux/elc.cpp +++ b/elenasrc3/elc/linux/elc.cpp @@ -171,7 +171,7 @@ int main(int argc, char* argv[]) ErrorProcessor errorProcessor(&Presenter::getInstance()); Project project(*dataPath, CURRENT_PLATFORM, &Presenter::getInstance()); LinuxLinker linker(&errorProcessor, &LinuxImageFormatter::getInstance(&project)); - CompilingProcess process(dataPath, nullptr, "", "", "", + CompilingProcess process(*dataPath, nullptr, "", "", "", &Presenter::getInstance(), &errorProcessor, VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); diff --git a/elenasrc3/elc/messages.h b/elenasrc3/elc/messages.h index 3f163d34f..e568e3ca6 100644 --- a/elenasrc3/elc/messages.h +++ b/elenasrc3/elc/messages.h @@ -10,7 +10,7 @@ namespace elena_lang { - constexpr auto MessageLength = 97; + constexpr auto MessageLength = 98; const Pair Messages[MessageLength] = { {errDuplicatedSymbol, errMsgDuplicatedSymbol}, @@ -95,6 +95,7 @@ namespace elena_lang {wrnUnsupportedOperator, wrnMsgUnsupportedOperator}, {errInvalidParserTarget, errMsgInvalidParserTarget}, {errInvalidParserTargetType, errMsgInvalidParserTargetType}, + {errTLSIsNotAllowed, errMsgTLSIsNotAllowed}, {wrnCallingItself, wrnMsgCallingItself}, {errAssigningToSelf, errMsgAssigningToSelf}, {wrnUnassignedVariable, wrnMsgUnassignedVariable}, diff --git a/elenasrc3/elc/project.h b/elenasrc3/elc/project.h index 65c4c9e51..0220a3749 100644 --- a/elenasrc3/elc/project.h +++ b/elenasrc3/elc/project.h @@ -18,6 +18,7 @@ namespace elena_lang class Project : public XmlProjectBase { FileEncoding _encoding; + SyntaxVersion _syntaxVersion; PathString _basePath; PathString _projectPath; @@ -59,6 +60,16 @@ namespace elena_lang PlatformType UITargetType(); PlatformType ThreadModeType(); + void setSyntaxVersion(SyntaxVersion version) + { + _syntaxVersion = version; + } + + SyntaxVersion getSyntaxVersion() + { + return _syntaxVersion; + } + ustr_t ProjectName() { return *_projectName; @@ -95,6 +106,7 @@ namespace elena_lang : XmlProjectBase(platform), _basePath(path), availableProfileList(DEFAULT_STR) { _encoding = FileEncoding::UTF8; + _syntaxVersion = SyntaxVersion::L6; _platform = platform; diff --git a/elenasrc3/elc/source.cpp b/elenasrc3/elc/source.cpp index ad0dfe876..53ef8d3b4 100644 --- a/elenasrc3/elc/source.cpp +++ b/elenasrc3/elc/source.cpp @@ -14,10 +14,10 @@ using namespace elena_lang; const char* source_dfa[40] = { - ".????????BB??B??????????????????BdFIRCDLDQDbDVQHEEEEEEEEEEDDDDYc`CCCCCCCCCCCCCCCCCCCCCCCCCCDeQDC?CCCCCCCCCCCCCCCCCCCCCCCCCCDDDDC", + ".????????BB??B??????????????????BdFIRCDLQQDbDVQHEEEEEEEEEEDDDDYc`CCCCCCCCCCCCCCCCCCCCCCCCCCDeQDC?CCCCCCCCCCCCCCCCCCCCCCCCCCDDDDC", "*********BB*********************B***********************************************************************************************", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAAAACCCCCCCCCCAAAAAAACCCCCCCCCCCCCCCCCCCCCCCCCCAAAACACCCCCCCCCCCCCCCCCCCCCCCCCCAAAAC", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAQAADQDAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAA", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAADAADQDAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAA", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$AEEEEEEEEEEAAAAAAAKKKKKKJJJJJJJJJJJJJJJJJJJJAAAAAAJJJJ$JJJJJJJJJJJJJJJJJJJJJJJAJJ", "?FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXAAAAAAAA", diff --git a/elenasrc3/elc/windows/elc.cpp b/elenasrc3/elc/windows/elc.cpp index ec36d2e0b..b4c7144a5 100644 --- a/elenasrc3/elc/windows/elc.cpp +++ b/elenasrc3/elc/windows/elc.cpp @@ -124,6 +124,14 @@ void handleOption(wchar_t* arg, IdentifierString& profile, Project& project, Com ErrorProcessor& errorProcessor, path_t appPath, bool& cleanMode) { switch (arg[1]) { + case 'e': + if (wstr_t(arg).compare(L"-el5")) { + project.setSyntaxVersion(SyntaxVersion::L5); + } + else if (wstr_t(arg).compare(L"-el6")) { + project.setSyntaxVersion(SyntaxVersion::L6); + } + break; case 'f': { IdentifierString setting(arg + 2); @@ -174,7 +182,8 @@ void handleOption(wchar_t* arg, IdentifierString& profile, Project& project, Com { IdentifierString configName(arg + 2); - project.loadConfigByName(appPath, *configName, true); + if(!project.loadConfigByName(appPath, *configName, true)) + errorProcessor.info(wrnInvalidConfig, *configName); break; } case 'v': @@ -318,7 +327,7 @@ int main() JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_SACKRESERV, 1, true }; ErrorProcessor errorProcessor(&Presenter::getInstance()); - CompilingProcess process(appPath, L"exe", L"", L"", L"", + CompilingProcess process(*appPath, L"exe", L"", L"", L"", &Presenter::getInstance(), &errorProcessor, VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); diff --git a/elenasrc3/elc/windows/ntimage.cpp b/elenasrc3/elc/windows/ntimage.cpp index d0fa4328b..63d6ab0b3 100644 --- a/elenasrc3/elc/windows/ntimage.cpp +++ b/elenasrc3/elc/windows/ntimage.cpp @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Compiler // // This header contains ELENA Executive Linker base class body -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "clicommon.h" @@ -291,7 +291,23 @@ void Win32NtImageFormatter::fixImportSection(MemoryBase* section, AddressSpace& void Win64NtImageFormatter :: createTLSSection(ImageProviderBase& provider, AddressSpace& map) { - + MemoryBase* tlsSection = provider.getTLSSection(); + if (tlsSection && tlsSection->length() > 0) { + pos_t tls_variable = (pos_t)provider.getTLSVariable(); + + // map IMAGE_TLS_DIRECTORY + MemoryWriter rdataWriter(provider.getRDataSection()); + map.tlsDirectory = rdataWriter.position(); + map.tlsSize = tlsSection->length(); + + // create IMAGE_TLS_DIRECTORY + rdataWriter.writeQReference(mskTLSRef64, 0); // StartAddressOfRawData + rdataWriter.writeQReference(mskTLSRef64, map.tlsSize); // EndAddressOfRawData + rdataWriter.writeQReference(mskDataRef64, tls_variable); // AddressOfIndex + rdataWriter.writeQWord(0); // AddressOfCallBacks + rdataWriter.writeDWord(0); // SizeOfZeroFill + rdataWriter.writeDWord(0); // Characteristics + } } void Win64NtImageFormatter :: createImportSection(ImageProviderBase& provider, RelocationMap& importMapping) diff --git a/elenasrc3/elc/windows/ntlinker64.cpp b/elenasrc3/elc/windows/ntlinker64.cpp index 883938000..8bb7678c8 100644 --- a/elenasrc3/elc/windows/ntlinker64.cpp +++ b/elenasrc3/elc/windows/ntlinker64.cpp @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Compiler // // This file contains ELENA Executive Win64 Linker class body -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "clicommon.h" @@ -87,11 +87,11 @@ void Win64NtLinker :: writeNtHeader(WinNtExecutableImage& image, FileWriter& fil header.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = image.addressSpace.import; header.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = image.addressSpace.importSize; - // - // // IMAGE_DIRECTORY_ENTRY_TLS - // if (tls_directory != 0xFFFFFFFF) { - // header.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = info.map.rdata + tls_directory; - // header.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = getSize(info.image->getTLSSection()); - // } + + // IMAGE_DIRECTORY_ENTRY_TLS + if (image.addressSpace.tlsDirectory != 0xFFFFFFFF) { + header.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = image.addressSpace.rdata + image.addressSpace.tlsDirectory; + header.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = image.addressSpace.tlsSize; + } file.write(&header, IMAGE_SIZEOF_NT_OPTIONAL_HEADER_64); } diff --git a/elenasrc3/elena-tests/bt_optimization.cpp b/elenasrc3/elena-tests/bt_optimization.cpp index 9855ae24e..81fd86278 100644 --- a/elenasrc3/elena-tests/bt_optimization.cpp +++ b/elenasrc3/elena-tests/bt_optimization.cpp @@ -45,6 +45,8 @@ constexpr auto S1_DirectCall_2 = "class (attribute -2147479546 ()nameattr (ident constexpr auto S1_DirectCall_3 = "class (attribute -2147479546 ()nameattr (identifier \"TestHelper\" ())method (nameattr (identifier \"myMethodInvoker\" ())code (expression (assign_operation (object (attribute -2147479539 ()identifier \"b1\" ())expression (message_operation (object (attribute -2147479534 ()identifier \"B\" ())))))expression (assign_operation (object (attribute -2147479539 ()identifier \"b2\" ())expression (message_operation (object (attribute -2147479534 ()identifier \"B\" ())))))expression (message_operation (object (identifier \"myMethod\" ())expression (object (identifier \"b1\" ()))expression (object (identifier \"b2\" ()))))))method (nameattr (identifier \"myMethod\" ())parameter (attribute -2147475445 ()array_type (type (identifier \"B\" ()))nameattr (identifier \"arg\" ()))code ()))"; +constexpr auto S1_MethodWithSignatureOfObject = "class (attribute -2147479546 ()nameattr (identifier \"Helper\" ())method (nameattr (identifier \"test\" ())parameter (type (identifier \"Object\" ())nameattr (identifier \"arg\" ()))code ())) class (attribute -2147467263 ()nameattr (identifier \"program\" ())attribute -2147479546 ()method (attribute -2147479540 ()code (expression (assign_operation (object (type (identifier \"Object\" ())identifier \"arg\" ())expression (object (integer \"2\" ()))))expression (message_operation (object (identifier \"Helper\" ()) message(identifier \"test\" ())expression (object (identifier \"arg\" ())))))))"; + // S2 Scenarion : lmbda constexpr auto S2_Func = "class (attribute -2147467263 ()attribute -2147479545 ()nameattr (identifier \"Func\" ())method (attribute -2147471358 ()nameattr (identifier \"function\" ())no_body ()))"; @@ -62,16 +64,18 @@ constexpr auto OptimizedBuildTree1_2 = "local_address -4 () saving_stack 1 () cl constexpr auto OptimizedBuildTree2 = "saving_int - 4 (size 4 ()value 2 ())"; constexpr auto OptimizedBuildTree4 = "saving_int -4 (size 4 ()value 3 ())local_address -4 ()copying -8 (size 4 ())addingint -8 (value 2 ())"; -constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 256 (message 3202 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop 6 (index -4 ()) unbox_call_message -2 (index 1 () length -4 () temp_var -8 () message 1089 ()) local 1 () saving_stack() argument() direct_call_op 3202 (type 5 ()) loading_index() free_varstack() close_frame() exit()) reserved 3 ()reserved_n 8 ())"; -constexpr auto BuildTree_VariadicSingleDispatch_2 = "tape(open_frame() assigning 1 () class_reference 2 () direct_call_op 544 (type 10 ()) assigning 2 () class_reference 8 () direct_call_op 544 (type 14 ()) assigning 3 () local 2 () saving_stack() argument() call_op 1089 () assigning 4 () local 3 () saving_stack() argument() call_op 1089 () assigning 5 () terminator() saving_stack 3 () local 5 () saving_stack 2 () local 4 () saving_stack 1 () class_reference 5 () saving_stack() argument() direct_call_op 3202 (type 5 ()) local 1 () close_frame() exit()) reserved 9 ()"; +constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 11 (message 3202 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop 6 (index -4 ()) unbox_call_message -2 (index 1 () length -4 () temp_var -8 () message 1089 ()) local 1 () saving_stack() argument() direct_call_op 2690 (type 5 ()) loading_index() free_varstack() close_frame() exit()) reserved 3 ()reserved_n 8 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_2 = "tape(open_frame() assigning 1 () class_reference 2 () direct_call_op 544 (type 10 ()) assigning 2 () class_reference 8 () direct_call_op 544 (type 15 ()) assigning 3 () local 2 () saving_stack() argument() call_op 1089 () assigning 4 () local 3 () saving_stack() argument() call_op 1089 () assigning 5 () terminator() saving_stack 3 () local 5 () saving_stack 2 () local 4 () saving_stack 1 () class_reference 5 () saving_stack() argument() direct_call_op 2690 (type 5 ()) local 1 () close_frame() exit()) reserved 9 ()"; -constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assigning 1 ()class_reference 8 ()direct_call_op 544 (type 15 ())assigning 2 ()class_reference 9 ()direct_call_op 544 (type 16 ())assigning 3 ()terminator ()saving_stack 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 7 ()saving_stack ()argument ()direct_call_op 4226 (type 7 ())local 1 ()close_frame ()exit ())reserved 7 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assigning 1 ()class_reference 8 ()direct_call_op 544 (type 16 ())assigning 2 ()class_reference 9 ()direct_call_op 544 (type 17 ())assigning 3 ()terminator ()saving_stack 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 7 ()saving_stack ()argument ()direct_call_op 3714 (type 7 ())local 1 ()close_frame ()exit ())reserved 7 ())"; -constexpr auto BuildTree_CallMethodWithoutTarget = "tape (open_frame ()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 6 ())assigning 2 ()local 2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()direct_call_op 3586 (type 4 ())local 1 ()close_frame ()exit ())reserved 4 ()"; -constexpr auto BuildTree_CallVariadicMethodWithoutTarget = "tape(open_frame()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 2 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 3 ()local 2 ()saving_stack()argument()call_op 1089 ()assigning 4 ()local 3 ()saving_stack()argument()call_op 1089 ()assigning 5 ()terminator()saving_stack 3 ()local 5 ()saving_stack 2 ()local 4 ()saving_stack 1 ()local 1 ()saving_stack()argument()direct_call_op 3714 (type 4 ())local 1 ()close_frame()exit())reserved 9 ()"; +constexpr auto BuildTree_CallMethodWithoutTarget = "tape (open_frame ()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 6 ())assigning 2 ()local 2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()direct_call_op 3074 (type 4 ())local 1 ()close_frame ()exit ())reserved 4 ()"; +constexpr auto BuildTree_CallVariadicMethodWithoutTarget = "tape(open_frame()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 2 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 3 ()local 2 ()saving_stack()argument()call_op 1089 ()assigning 4 ()local 3 ()saving_stack()argument()call_op 1089 ()assigning 5 ()terminator()saving_stack 3 ()local 5 ()saving_stack 2 ()local 4 ()saving_stack 1 ()local 1 ()saving_stack()argument()direct_call_op 3202 (type 4 ())local 1 ()close_frame()exit())reserved 9 ()"; constexpr auto BuildTree_LambdaCallPrivate = "tape (open_frame ()assigning 1 ()local 1 ()field ()saving_stack ()argument ()direct_call_op 3329 (type 3 ())close_frame ()exit ())reserved 2 ()"; +constexpr auto BuildTree_CallMethodWithSignatureOfObject = "tape (open_frame ()assigning 1 ()int_literal 2 (value 2 ())assigning 2 ()local 2 ()saving_stack 1 ()class_reference 3 ()saving_stack ()argument ()direct_call_op 1538 (type 3 ())local 1 ()close_frame ()exit ())reserved 4 ())"; + constexpr auto PackedStructSize = 20; constexpr auto ComplexStructOffset2 = 4; @@ -89,16 +93,18 @@ constexpr auto OptimizedBuildTree1_2 = "local_address -8 () saving_stack 1 () cl constexpr auto OptimizedBuildTree2 = "saving_int - 8 (size 4 ()value 2 ())"; constexpr auto OptimizedBuildTree4 = "saving_int -8 (size 4 ()value 3 ())local_address -8 ()copying -24 (size 4 ())addingint -24 (value 2 ())"; -constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 256 (message 3202 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop 6 (index -8 ()) unbox_call_message -2 (index 1 () length -8 () temp_var -24 () message 1089 ()) local 1 () saving_stack() argument() direct_call_op 3202 (type 5 ()) loading_index() free_varstack() close_frame() exit()) reserved 4 ()reserved_n 32 ())"; -constexpr auto BuildTree_VariadicSingleDispatch_2 = "tape(open_frame() assigning 1 () class_reference 2 () direct_call_op 544 (type 10 ()) assigning 2 () class_reference 8 () direct_call_op 544 (type 14 ()) assigning 3 () local 2 () saving_stack() argument() call_op 1089 () assigning 4 () local 3 () saving_stack() argument() call_op 1089 () assigning 5 () terminator() saving_stack 3 () local 5 () saving_stack 2 () local 4 () saving_stack 1 () class_reference 5 () saving_stack() argument() direct_call_op 3202 (type 5 ()) local 1 () close_frame() exit()) reserved 10 ()"; +constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 11 (message 3202 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop 6 (index -8 ()) unbox_call_message -2 (index 1 () length -8 () temp_var -24 () message 1089 ()) local 1 () saving_stack() argument() direct_call_op 2690 (type 5 ()) loading_index() free_varstack() close_frame() exit()) reserved 4 ()reserved_n 32 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_2 = "tape(open_frame() assigning 1 () class_reference 2 () direct_call_op 544 (type 10 ()) assigning 2 () class_reference 8 () direct_call_op 544 (type 15 ()) assigning 3 () local 2 () saving_stack() argument() call_op 1089 () assigning 4 () local 3 () saving_stack() argument() call_op 1089 () assigning 5 () terminator() saving_stack 3 () local 5 () saving_stack 2 () local 4 () saving_stack 1 () class_reference 5 () saving_stack() argument() direct_call_op 2690 (type 5 ()) local 1 () close_frame() exit()) reserved 10 ()"; -constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assigning 1 ()class_reference 8 ()direct_call_op 544 (type 15 ())assigning 2 ()class_reference 9 ()direct_call_op 544 (type 16 ())assigning 3 ()terminator ()saving_stack 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 7 ()saving_stack ()argument ()direct_call_op 4226 (type 7 ())local 1 ()close_frame ()exit ())reserved 8 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assigning 1 ()class_reference 8 ()direct_call_op 544 (type 16 ())assigning 2 ()class_reference 9 ()direct_call_op 544 (type 17 ())assigning 3 ()terminator ()saving_stack 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 7 ()saving_stack ()argument ()direct_call_op 3714 (type 7 ())local 1 ()close_frame ()exit ())reserved 8 ())"; -constexpr auto BuildTree_CallMethodWithoutTarget = "tape (open_frame ()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 6 ())assigning 2 ()local 2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()direct_call_op 3586 (type 4 ())local 1 ()close_frame ()exit ())reserved 4 ()"; -constexpr auto BuildTree_CallVariadicMethodWithoutTarget = "tape(open_frame()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 2 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 3 ()local 2 ()saving_stack()argument()call_op 1089 ()assigning 4 ()local 3 ()saving_stack()argument()call_op 1089 ()assigning 5 ()terminator()saving_stack 3 ()local 5 ()saving_stack 2 ()local 4 ()saving_stack 1 ()local 1 ()saving_stack()argument()direct_call_op 3714 (type 4 ())local 1 ()close_frame()exit())reserved 10 ()"; +constexpr auto BuildTree_CallMethodWithoutTarget = "tape (open_frame ()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 6 ())assigning 2 ()local 2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()direct_call_op 3074 (type 4 ())local 1 ()close_frame ()exit ())reserved 4 ()"; +constexpr auto BuildTree_CallVariadicMethodWithoutTarget = "tape(open_frame()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 2 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 3 ()local 2 ()saving_stack()argument()call_op 1089 ()assigning 4 ()local 3 ()saving_stack()argument()call_op 1089 ()assigning 5 ()terminator()saving_stack 3 ()local 5 ()saving_stack 2 ()local 4 ()saving_stack 1 ()local 1 ()saving_stack()argument()direct_call_op 3202 (type 4 ())local 1 ()close_frame()exit())reserved 10 ()"; constexpr auto BuildTree_LambdaCallPrivate = "tape (open_frame ()assigning 1 ()local 1 ()field ()saving_stack ()argument ()direct_call_op 3329 (type 3 ())close_frame ()exit ())reserved 4 ()"; +constexpr auto BuildTree_CallMethodWithSignatureOfObject = "tape (open_frame ()assigning 1 ()int_literal 2 (value 2 ())assigning 2 ()local 2 ()saving_stack 1 ()class_reference 3 ()saving_stack ()argument ()direct_call_op 1538 (type 3 ())local 1 ()close_frame ()exit ())reserved 4 ())"; + constexpr auto PackedStructSize = 24; constexpr auto ComplexStructOffset2 = 8; @@ -516,6 +522,20 @@ void CallVariadocMethodWithoutTarget :: SetUp() BuildTreeSerializer::load(BuildTree_CallVariadicMethodWithoutTarget, controlOutputNode); } +// --- CallMethodWithSignatureOfSuperClass --- + +void CallMethodWithSignatureOfSuperClass :: SetUp() +{ + MethodScenarioTest::SetUp(); + + LoadDeclarationScenario(S_DefaultNamespace_3, S_IntNumber, S1_MethodWithSignatureOfObject); + + BuildTreeSerializer::load(BuildTree_CallMethodWithSignatureOfObject, controlOutputNode); + + targetRef = 4; + intNumberRef = 2; +} + // --- LambdaTest --- BuildNode LambdaTest :: findOutput(BuildNode root) @@ -593,7 +613,7 @@ void Lambda_CallingPrivateMethod :: SetUp() funcRef = 2; targetRef = 3; - outputRef = 0x100; + outputRef = 6; } // --- IntOperation --- diff --git a/elenasrc3/elena-tests/bt_optimization.h b/elenasrc3/elena-tests/bt_optimization.h index 48d1b5b85..1d437a2e4 100644 --- a/elenasrc3/elena-tests/bt_optimization.h +++ b/elenasrc3/elena-tests/bt_optimization.h @@ -170,6 +170,12 @@ namespace elena_lang void SetUp() override; }; + class CallMethodWithSignatureOfSuperClass : public MethodScenarioTest + { + protected: + void SetUp() override; + }; + class LambdaTest : public ScenarioTest { protected: diff --git a/elenasrc3/elena-tests/build_tests.cpp b/elenasrc3/elena-tests/build_tests.cpp index dec6425ae..6c1a0ef24 100644 --- a/elenasrc3/elena-tests/build_tests.cpp +++ b/elenasrc3/elena-tests/build_tests.cpp @@ -61,6 +61,11 @@ TEST_F(CallVariadocMethodWithoutTarget, BuildTest) runTest(false); } +TEST_F(CallMethodWithSignatureOfSuperClass, BuildTest) +{ + runTest(); +} + // Test scenario : E.load(new C(), new D()); where: class E { constructor load(params B[] args) {}}, C:B and D:B TEST_F(VariadicCompiletimeSingleDispatch_WithDifferentArgs, BuildTest) { diff --git a/elenasrc3/elena-tests/constructor_tests.cpp b/elenasrc3/elena-tests/constructor_tests.cpp index 9e3e33f71..71efe22c9 100644 --- a/elenasrc3/elena-tests/constructor_tests.cpp +++ b/elenasrc3/elena-tests/constructor_tests.cpp @@ -16,12 +16,12 @@ constexpr auto S_PrivateConstructorTest = "class (nameattr (identifier \"X\" ()) #ifdef _M_IX86 -constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference - 2 ()saving_stack()varg_sop 6 (index - 4 ())unbox_call_message - 2 (index 1 ()length - 4 ()temp_var - 8 ()message 1601 ())class_reference 6 ()saving_stack()argument()direct_call_op 5250 (type 12 ())loading_index() free_varstack() going_to_eop() close_frame()exit())reserved 3 ()reserved_n 8 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference - 2 ()saving_stack()varg_sop 6 (index - 4 ())unbox_call_message - 2 (index 1 ()length - 4 ()temp_var - 8 ()message 1601 ())class_reference 6 ()saving_stack()argument()direct_call_op 4226 (type 13 ())loading_index() free_varstack() going_to_eop() close_frame()exit())reserved 3 ()reserved_n 8 ())"; constexpr auto BuildTree_PrivateConstructorTest = "tape(open_frame() direct_call_op 800(type 6()) assigning 1 ()local -2 ()saving_stack()create_struct 4 (type 2()) copying_to_acc 2 (size 4 ()) assigning 2() local 2() saving_stack () local 1() field_assign () local 1() close_frame()exit())reserved 3 ())"; #elif _M_X64 -constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference -2 ()saving_stack()varg_sop 6 (index -8 ())unbox_call_message -2 (index 1 ()length -8 ()temp_var -24 ()message 1601 ())class_reference 6 ()saving_stack()argument()direct_call_op 5250 (type 12 ())loading_index() free_varstack() going_to_eop() close_frame()exit())reserved 4 ()reserved_n 32 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference -2 ()saving_stack()varg_sop 6 (index -8 ())unbox_call_message -2 (index 1 ()length -8 ()temp_var -24 ()message 1601 ())class_reference 6 ()saving_stack()argument()direct_call_op 4226 (type 13 ())loading_index() free_varstack() going_to_eop() close_frame()exit())reserved 4 ()reserved_n 32 ())"; constexpr auto BuildTree_PrivateConstructorTest = "tape(open_frame() direct_call_op 800(type 6()) assigning 1 ()local -2 ()saving_stack()create_struct 4 (type 2()) copying_to_acc 2 (size 4 ()) assigning 2() local 2() saving_stack () local 1() field_assign () local 1() close_frame()exit())reserved 4 ())"; #endif diff --git a/elenasrc3/elena-tests/declaration.cpp b/elenasrc3/elena-tests/declaration.cpp index 3ca48d338..e75dccf12 100644 --- a/elenasrc3/elena-tests/declaration.cpp +++ b/elenasrc3/elena-tests/declaration.cpp @@ -54,7 +54,7 @@ void DeclarationFixture :: runTest() getAppPath(appPath); StringTextReader reader(_src); - PathString syntaxPath(*appPath, SYNTAX_FILE); + PathString syntaxPath(*appPath, SYNTAX60_FILE); FileReader syntax(*syntaxPath, FileRBMode, FileEncoding::Raw, false); auto parser = new Parser(&syntax, terminals, nullptr); diff --git a/elenasrc3/elena-tests/elena-tests.vcxproj b/elenasrc3/elena-tests/elena-tests.vcxproj index 3dbb030e5..ac5f9e611 100644 --- a/elenasrc3/elena-tests/elena-tests.vcxproj +++ b/elenasrc3/elena-tests/elena-tests.vcxproj @@ -35,20 +35,20 @@ ..\..\bin\ ..\temp\elena-tests\ - elena-tests + elena-tests-x86 ..\..\bin\ - elena-tests64 + elena-tests-x64 ..\temp\elena-tests64\ ..\..\bin\ ..\temp\elena-tests\ - elena-tests + elena-tests-x86 - elena-tests64 + elena-tests-x64 ..\..\bin\ ..\temp\elena-tests64\ diff --git a/elenasrc3/elena-tests/tests_common.cpp b/elenasrc3/elena-tests/tests_common.cpp index e240f1c4f..d924d1234 100644 --- a/elenasrc3/elena-tests/tests_common.cpp +++ b/elenasrc3/elena-tests/tests_common.cpp @@ -55,7 +55,10 @@ bool TestModuleScope :: withValidation() ref_t TestModuleScope :: mapAnonymous(ustr_t prefix) { - return _anonymousRef++; + IdentifierString name("'", prefix, INLINE_CLASSNAME); + name.appendInt(_anonymousRef++); + + return module->mapReference(*name); } ref_t TestModuleScope :: mapNewIdentifier(ustr_t ns, ustr_t identifier, Visibility visibility) @@ -120,7 +123,15 @@ ref_t TestModuleScope :: resolveWeakTemplateReferenceID(ref_t reference) SectionInfo TestModuleScope :: getSection(ustr_t referenceName, ref_t mask, bool silentMode) { - return {}; + SectionInfo info = {}; + + if (isWeakReference(referenceName)) { + info.module = module; + info.reference = module->mapReference(referenceName, true); + info.section = module->mapSection(info.reference | mask, true); + } + + return info; } MemoryBase* TestModuleScope :: mapSection(ref_t reference, bool existing) @@ -295,14 +306,15 @@ void BaseFixture :: LoadDeclarationScenario(ustr_t common, ustr_t descr) void BaseFixture :: LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2) { - IdentifierString descr(descr1, " ", descr2); - DynamicUStr syntax(common); size_t index = common.findStr("$1"); if (index != NOTFOUND_POS) { syntax.cut(index, 2); - syntax.insert(*descr, index); + + syntax.insert(descr2, index); + syntax.insert(" ", index); + syntax.insert(descr1, index); } SyntaxTreeSerializer::load(syntax.str(), declarationNode); diff --git a/elenasrc3/elenart/elenartmachine.cpp b/elenasrc3/elenart/elenartmachine.cpp index 385022969..deee3d773 100644 --- a/elenasrc3/elenart/elenartmachine.cpp +++ b/elenasrc3/elenart/elenartmachine.cpp @@ -328,7 +328,7 @@ void ELENARTMachine :: startSTA(SystemEnv* env, void* entry) size_t ELENARTMachine :: allocateThreadEntry(SystemEnv* env) { - if (env->th_table->counter < env->threadCounter) { + if (env->th_table && env->th_table->counter < env->threadCounter) { size_t index = env->th_table->counter; env->th_table->counter++; @@ -345,7 +345,7 @@ void ELENARTMachine :: clearThreadEntry(SystemEnv* env, size_t index) env->th_table->slots[index].arg = nullptr; } -void* ELENARTMachine :: allocateThread(SystemEnv* env, void* arg, void* threadProc, int flags) +void* ELENARTMachine :: allocateThread(SystemEnv* env, void* arg, void* threadProc, int stackSize, int flags) { size_t index = allocateThreadEntry(env); @@ -354,7 +354,7 @@ void* ELENARTMachine :: allocateThread(SystemEnv* env, void* arg, void* threadPr env->th_table->slots[index].arg = arg; - return __routineProvider.CreateThread(index, flags, threadProc); + return __routineProvider.CreateThread(index, stackSize, flags, threadProc); } void ELENARTMachine :: startThread(SystemEnv* env, void* entry, int index) diff --git a/elenasrc3/elenart/elenartmachine.h b/elenasrc3/elenart/elenartmachine.h index 5706fd142..4099711d4 100644 --- a/elenasrc3/elenart/elenartmachine.h +++ b/elenasrc3/elenart/elenartmachine.h @@ -73,7 +73,7 @@ namespace elena_lang size_t allocateThreadEntry(SystemEnv* env); void clearThreadEntry(SystemEnv* env, size_t index); - void* allocateThread(SystemEnv* env, void* arg, void* threadProc, int flags); + void* allocateThread(SystemEnv* env, void* arg, void* threadProc, int stackSize, int flags); unsigned int getRandomNumber(SeedStruct& seed) { diff --git a/elenasrc3/elenart/rtcommon.h b/elenasrc3/elenart/rtcommon.h index ff53fa46d..9aea36d0e 100644 --- a/elenasrc3/elenart/rtcommon.h +++ b/elenasrc3/elenart/rtcommon.h @@ -14,7 +14,7 @@ namespace elena_lang { -#define ELENART_REVISION_NUMBER 0x0006 +#define ELENART_REVISION_NUMBER 0x0008 } diff --git a/elenasrc3/elenart/windows/dllmain.cpp b/elenasrc3/elenart/windows/dllmain.cpp index e10e49e69..9e5053c4c 100644 --- a/elenasrc3/elenart/windows/dllmain.cpp +++ b/elenasrc3/elenart/windows/dllmain.cpp @@ -103,9 +103,9 @@ EXTERN_DLL_EXPORT void ExitLA(int retVal) } // NOTE : arg must be unique for every separate thread -EXTERN_DLL_EXPORT void* CreateThreadLA(void* arg, void* threadProc, int flags) +EXTERN_DLL_EXPORT void* CreateThreadLA(void* arg, void* threadProc, int stackSize, int flags) { - return machine->allocateThread(systemEnv, arg, threadProc, flags); + return machine->allocateThread(systemEnv, arg, threadProc, stackSize, flags); } EXTERN_DLL_EXPORT void InitThreadLA(SystemEnv* env, void* criricalHandler, int index) @@ -141,16 +141,11 @@ EXTERN_DLL_EXPORT void* CollectPermGCLA(size_t size) return __routineProvider.GCRoutinePerm(systemEnv->gc_table, size); } -EXTERN_DLL_EXPORT void* CollectGCLA(void* roots, size_t size) +EXTERN_DLL_EXPORT void* CollectGCLA(void* roots, size_t size, bool fullMode) { // printf("CollectGCLA %llx %llx\n", (long long)roots, size); - return __routineProvider.GCRoutine(systemEnv->gc_table, (GCRoot*)roots, size, false); -} - -EXTERN_DLL_EXPORT void* ForcedCollectGCLA(void* roots, int fullMode) -{ - return __routineProvider.GCRoutine(systemEnv->gc_table, (GCRoot*)roots, INVALID_SIZE, fullMode != 0); + return __routineProvider.GCRoutine(systemEnv->gc_table, (GCRoot*)roots, size, fullMode); } EXTERN_DLL_EXPORT size_t LoadMessageNameLA(size_t message, char* buffer, size_t length) diff --git a/elenasrc3/engine/bcwriter.cpp b/elenasrc3/engine/bcwriter.cpp index ed9751cb8..3cc0c44fb 100644 --- a/elenasrc3/engine/bcwriter.cpp +++ b/elenasrc3/engine/bcwriter.cpp @@ -1674,6 +1674,11 @@ void staticVarOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) tape.write(ByteCode::PeekR, node.arg.reference | mskStaticVariable); } +void threadVarOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +{ + tape.write(ByteCode::PeekTLS, node.arg.reference | mskTLSVariable); +} + void staticBegin(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) { tape.newLabel(); // declare symbol-end label @@ -1689,6 +1694,21 @@ void staticEnd(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) tape.setLabel(); } +void threadVarBegin(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +{ + tape.newLabel(); // declare symbol-end label + tape.write(ByteCode::PeekTLS, node.arg.reference | mskTLSVariable); + tape.write(ByteCode::CmpR, 0); + tape.write(ByteCode::Jne, PseudoArg::CurrentLabel); +} + +void threadVarEnd(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +{ + tape.write(ByteCode::StoreTLS, node.arg.reference | mskTLSVariable); + + tape.setLabel(); +} + void classOp(CommandTape& tape, BuildNode& node, TapeScope&) { switch (node.arg.value) { @@ -1988,6 +2008,11 @@ void staticAssigning(CommandTape& tape, BuildNode& node, TapeScope&) tape.write(ByteCode::StoreR, node.arg.value | mskStaticVariable); } +void threadVarAssigning(CommandTape& tape, BuildNode& node, TapeScope&) +{ + tape.write(ByteCode::StoreTLS, node.arg.value | mskTLSVariable); +} + void freeStack(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::Neg); @@ -2110,7 +2135,8 @@ ByteCodeWriter::Saver commands[] = copyingToAccExact, savingInt, addingInt, loadingAccToIndex, indexOp, savingIndexToAcc, continueOp, semiDirectCallOp, intRealOp, realIntOp, copyingToLocalArr, loadingStackDump, savingStackDump, savingFloatIndex, intCopyingToAccField, intOpWithConst, - uint8CondOp, uint16CondOp, intLongOp, distrConstant, unboxingAndCallMessage + uint8CondOp, uint16CondOp, intLongOp, distrConstant, unboxingAndCallMessage, threadVarOp, threadVarAssigning, threadVarBegin, + threadVarEnd }; inline bool duplicateBreakpoints(BuildNode lastNode) @@ -2967,7 +2993,7 @@ void ByteCodeWriter :: saveNativeBranching(CommandTape& tape, BuildNode node, Ta } } -void ByteCodeWriter::saveShortCircuitOp(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) +void ByteCodeWriter :: saveShortCircuitOp(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) { int endLabel = tape.newLabel(); @@ -2977,8 +3003,12 @@ void ByteCodeWriter::saveShortCircuitOp(CommandTape& tape, BuildNode node, TapeS BuildNode lnode = node.findChild(BuildKey::Tape); BuildNode rnode = lnode.nextNode(); - saveTape(tape, lnode, tapeScope, paths, tapeOptMode, false); + if (rnode != BuildKey::None) { + saveTape(tape, lnode, tapeScope, paths, tapeOptMode, false); + } + else rnode = lnode; + ByteCode jmpCode = ByteCode::Jeq; switch (node.arg.reference) { case AND_OPERATOR_ID: tape.write(ByteCode::CmpR, falseRef | mskVMTRef); @@ -2986,10 +3016,14 @@ void ByteCodeWriter::saveShortCircuitOp(CommandTape& tape, BuildNode node, TapeS case OR_OPERATOR_ID: tape.write(ByteCode::CmpR, trueRef | mskVMTRef); break; + case ISNIL_OPERATOR_ID: + tape.write(ByteCode::CmpR, 0); + jmpCode = ByteCode::Jne; + break; } // tape.write(ByteCode::BreakLabel); // !! temporally, to prevent if-optimization - tape.write(ByteCode::Jeq, PseudoArg::CurrentLabel); + tape.write(jmpCode, PseudoArg::CurrentLabel); saveTape(tape, rnode, tapeScope, paths, tapeOptMode, false); diff --git a/elenasrc3/engine/buildtree.h b/elenasrc3/engine/buildtree.h index 25d68d34f..22df03415 100644 --- a/elenasrc3/engine/buildtree.h +++ b/elenasrc3/engine/buildtree.h @@ -160,9 +160,12 @@ namespace elena_lang IntLongOp = 0x0082, DistributedTypeList = 0x0083, UnboxAndCallMessage = 0x0084, - NilRefBranchOp = 0x0085, + ThreadVar = 0x0085, + ThreadVarAssigning = 0x0086, + OpenThreadVar = 0x0087, + CloseThreadVar = 0x0088, - MaxOperationalKey = 0x0085, + MaxOperationalKey = 0x0088, Import = 0x0090, DictionaryOp = 0x0091, @@ -186,6 +189,7 @@ namespace elena_lang StackCondOp = 0x00A3, YieldDispatch = 0x00A4, TernaryOp = 0x00A5, + NilRefBranchOp = 0x00A6, VariableInfo = 0x00B0, Variable = 0x00B1, diff --git a/elenasrc3/engine/bytecode.cpp b/elenasrc3/engine/bytecode.cpp index abe181f55..c8ce5e690 100644 --- a/elenasrc3/engine/bytecode.cpp +++ b/elenasrc3/engine/bytecode.cpp @@ -48,7 +48,7 @@ const char* _fnOpcodes[256] = "peek fp", "peek sp", "lsave dp", "lsave sp", "lload dp", "xfill", "xstore i", "set sp", "call", "call vt", "jump", "jeq", "jne", "jump vt", "xredirect mssg", "jlt", - "jge", "jgr", "jle", OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, + "jge", "jgr", "jle", "peek tls", "store tls", OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, "cmp", "fcmp", "icmp", "tst flag", "tst n", "tst mssg", "xcmp sp", OPCODE_UNKNOWN, "cmp fp", "cmp sp", "extclose", "lload sp", "load sp", "xloadarg fp", "xcreate", "system", diff --git a/elenasrc3/engine/bytecode.h b/elenasrc3/engine/bytecode.h index 75bfb82e3..313174b66 100644 --- a/elenasrc3/engine/bytecode.h +++ b/elenasrc3/engine/bytecode.h @@ -153,6 +153,8 @@ namespace elena_lang Jge = 0xB8, Jgr = 0xB9, Jle = 0xBA, + PeekTLS = 0xBB, + StoreTLS = 0xBC, CmpR = 0xC0, FCmpN = 0xC1, diff --git a/elenasrc3/engine/codescope.cpp b/elenasrc3/engine/codescope.cpp index 1bdd93edb..4221724b7 100644 --- a/elenasrc3/engine/codescope.cpp +++ b/elenasrc3/engine/codescope.cpp @@ -64,6 +64,8 @@ addr_t ReferenceMapper :: resolveReference(ustr_t referenceName, ref_t sectionMa case mskMssgLiteralRef: case mskExtMssgLiteralRef: return _mssgReferences.get(referenceName); + case mskTLSVariable: + return _tlsReferences.get(referenceName); default: return INVALID_ADDR; } @@ -114,6 +116,9 @@ void ReferenceMapper :: mapReference(ustr_t referenceName, addr_t address, ref_t case mskStaticVariable: _statReferences.add(referenceName, address); break; + case mskTLSVariable: + _tlsReferences.add(referenceName, address); + break; default: break; } diff --git a/elenasrc3/engine/codescope.h b/elenasrc3/engine/codescope.h index 70b887b40..2591b6603 100644 --- a/elenasrc3/engine/codescope.h +++ b/elenasrc3/engine/codescope.h @@ -33,6 +33,7 @@ namespace elena_lang AddressMap _mssgReferences, _subjReferences; AddressMap _dataReferences; AddressMap _statReferences; + AddressMap _tlsReferences; ReferenceMap _actionNames; ActionMap _actions; @@ -80,6 +81,7 @@ namespace elena_lang _subjReferences(INVALID_ADDR), _dataReferences(INVALID_ADDR), _statReferences(INVALID_ADDR), + _tlsReferences(INVALID_ADDR), _actionNames(0), _actions(0), _lazyReferences({}), diff --git a/elenasrc3/engine/core.h b/elenasrc3/engine/core.h index 7c1f3e188..63c18dd86 100644 --- a/elenasrc3/engine/core.h +++ b/elenasrc3/engine/core.h @@ -2,7 +2,7 @@ // // This file contains common ELENA Core constants // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //------------------------------------------------------------------------------ #ifndef CORE_H @@ -190,6 +190,7 @@ namespace elena_lang struct SystemEnv { size_t stat_counter; + size_t tlsSize; GCTable* gc_table; ThreadContent* th_single_content; // NOTE : used only for STA ThreadTable* th_table; // NOTE : used only for MTA diff --git a/elenasrc3/engine/elena.h b/elenasrc3/engine/elena.h index 81ed93fe4..2634c09af 100644 --- a/elenasrc3/engine/elena.h +++ b/elenasrc3/engine/elena.h @@ -423,6 +423,7 @@ namespace elena_lang virtual void info(int code, ustr_t arg, ustr_t arg2) = 0; virtual void raiseInternalError(int code) = 0; + virtual void raiseError(int code) = 0; virtual void raiseError(int code, ustr_t arg) = 0; virtual void raisePathError(int code, path_t pathArg) = 0; virtual void raisePathWarning(int code, path_t pathArg) = 0; @@ -558,6 +559,7 @@ namespace elena_lang virtual void compileOutputTypeList(ReferenceHelperBase* helper, MemoryWriter& writer, CachedOutputTypeList& outputTypeList) = 0; virtual pos_t getStaticCounter(MemoryBase* statSection, bool emptyNotAllowed = false) = 0; + virtual pos_t getTLSSize(MemoryBase* tlsSection) = 0; virtual pos_t getVMTLength(void* targetVMT) = 0; virtual addr_t findMethodAddress(void* entries, mssg_t message) = 0; @@ -608,7 +610,7 @@ namespace elena_lang virtual void* getSystemEnv() = 0; - virtual void updateEnvironment(MemoryBase* rdata, pos_t staticCounter, bool virtualMode) = 0; + virtual void updateEnvironment(MemoryBase* rdata, pos_t staticCounter, pos_t tlsSize, bool virtualMode) = 0; virtual void updateVoidObject(MemoryBase* rdata, addr_t superAddress, bool virtualMode) = 0; virtual void allocateVariable(MemoryWriter& writer) = 0; diff --git a/elenasrc3/engine/elenaconst.h b/elenasrc3/engine/elenaconst.h index d60c23020..39e9be151 100644 --- a/elenasrc3/engine/elenaconst.h +++ b/elenasrc3/engine/elenaconst.h @@ -149,6 +149,7 @@ namespace elena_lang constexpr auto INVOKE_MESSAGE = "#invoke"; constexpr auto TRY_INVOKE_MESSAGE = "#try_invoke"; constexpr auto INIT_MESSAGE = "#init"; + constexpr auto CLASS_INIT_MESSAGE = "#class_init"; constexpr auto NEXT_MESSAGE = "next"; constexpr auto CURRENT_FIELD = "__current"; @@ -239,6 +240,13 @@ namespace elena_lang WrongStructure }; + // --- ELENA Syntax Version --- + enum class SyntaxVersion + { + L6 = 0, + L5 = 1 + }; + // --- ELENA Platform type --- enum class PlatformType { None = 0x00000, @@ -394,6 +402,7 @@ namespace elena_lang constexpr ref_t mskMssgNameLiteralRef = 0x25000000u; constexpr ref_t mskPackageRef = 0x26000000u; constexpr ref_t mskDistrTypeListRef = 0x27000000u; + constexpr ref_t mskTLSVariable = 0x28000000u; // --- Image reference types --- constexpr ref_t mskCodeRef = 0x01000000u; @@ -419,6 +428,7 @@ namespace elena_lang constexpr ref_t mskRef32Lo12_8 = 0x50000000u; // <32 bit address> & 0xFFF ; for ARM64 : it shoulb be b21:10 constexpr ref_t mskXDisp32Hi = 0x30000000u; constexpr ref_t mskXDisp32Lo = 0x70000000u; + constexpr ref_t mskOffset32 = 0xF0000000u; // --- VAddress reference types ---- constexpr ref_t mskCodeRef32 = 0x81000000u; @@ -480,6 +490,7 @@ namespace elena_lang constexpr ref_t mskStatXDisp32Lo = 0x77000000u; constexpr ref_t mskTLSRef32 = 0x88000000u; + constexpr ref_t mskTLSRef64 = 0xC8000000u; // --- Address predefined references --- constexpr ref_t INV_ARG = 0x00000100u; diff --git a/elenasrc3/engine/elenamachine.cpp b/elenasrc3/engine/elenamachine.cpp index 0ecf5bff8..6e368f2ad 100644 --- a/elenasrc3/engine/elenamachine.cpp +++ b/elenasrc3/engine/elenamachine.cpp @@ -52,7 +52,7 @@ inline uintptr_t RetrieveVMT(uintptr_t ptr) uintptr_t ELENAMachine :: createPermString(SystemEnv* env, ustr_t s, uintptr_t classPtr) { size_t nameLen = getlength(s) + 1; - uintptr_t nameAddr = (uintptr_t)SystemRoutineProvider::GCRoutinePerm(env->gc_table, align(nameLen + elObjectOffset, gcPageSize)); + uintptr_t nameAddr = (uintptr_t)SystemRoutineProvider::GCRoutinePerm(env->gc_table, alignSize(nameLen + elObjectOffset, gcPageSize)); StrConvertor::copy((char*)nameAddr, s.str(), nameLen, nameLen); @@ -67,7 +67,7 @@ uintptr_t ELENAMachine :: createPermVMT(SystemEnv* env, size_t size) { size += sizeof(ObjectPage); - uintptr_t addr = (uintptr_t)SystemRoutineProvider::GCRoutinePerm(env->gc_table, align(size, gcPageSize)); + uintptr_t addr = (uintptr_t)SystemRoutineProvider::GCRoutinePerm(env->gc_table, alignSize(size, gcPageSize)); ObjectPage* header = (ObjectPage*)(addr - elObjectOffset); header->size = size; diff --git a/elenasrc3/engine/elenamachine.h b/elenasrc3/engine/elenamachine.h index 4ce9f5c0b..4fcc2827f 100644 --- a/elenasrc3/engine/elenamachine.h +++ b/elenasrc3/engine/elenamachine.h @@ -131,7 +131,7 @@ namespace elena_lang static void InitRandomSeed(SeedStruct& seed, long long seedNumber); static unsigned int GetRandomNumber(SeedStruct& seed); - static void* CreateThread(size_t tt_index, int flags, void* threadProc); + static void* CreateThread(size_t tt_index, int stackSize, int flags, void* threadProc); static void StopThread(); diff --git a/elenasrc3/engine/gcroutines.cpp b/elenasrc3/engine/gcroutines.cpp index 396e07418..78ed792d0 100644 --- a/elenasrc3/engine/gcroutines.cpp +++ b/elenasrc3/engine/gcroutines.cpp @@ -463,7 +463,7 @@ void* SystemRoutineProvider :: GCRoutine(GCTable* table, GCRoot* roots, size_t s FullCollect(table, roots); - if (size == INVALID_SIZE) + if (size == 0) return nullptr; if (table->gc_yg_end - table->gc_yg_current < size) { @@ -496,7 +496,7 @@ void* SystemRoutineProvider :: GCRoutine(GCTable* table, GCRoot* roots, size_t s return (void*)getObjectPtr(allocated); } } - else { + else if (size > 0) { uintptr_t allocated = table->gc_yg_current; table->gc_yg_current += size; diff --git a/elenasrc3/engine/jitcompiler.cpp b/elenasrc3/engine/jitcompiler.cpp index 2398f698e..be0445686 100644 --- a/elenasrc3/engine/jitcompiler.cpp +++ b/elenasrc3/engine/jitcompiler.cpp @@ -52,7 +52,7 @@ CodeGenerator _codeGenerators[256] = loadFrameIndexOp, loadStackIndexOp, loadFrameDispOp, loadStackIndexOp, loadFrameDispOp, loadROp, loadFieldIndexOp, loadStackIndexOp, loadCallROp, loadVMTIndexOp, compileJump, compileJeq, compileJne, loadVMTIndexOp, loadMOp, compileJlt, - compileJge, compileJgr, compileJle, loadNop, loadNop, loadNop, loadNop, loadNop, + compileJge, compileJgr, compileJle, loadTLSOp, loadTLSOp, loadNop, loadNop, loadNop, loadROp, loadIOp, loadIOp, loadNOp, loadNOp, loadMOp, loadStackIndexOp, loadNop, loadFrameIndexOp, loadStackIndexOp, compileClose, loadStackIndexOp, loadStackIndexOp, loadFrameIndexOp, loadROp, loadSysOp, @@ -90,7 +90,7 @@ constexpr ref_t coreFunctions[coreFunctionNumber] = }; // preloaded bc commands -constexpr size_t bcCommandNumber = 176; +constexpr size_t bcCommandNumber = 178; constexpr ByteCode bcCommands[bcCommandNumber] = { ByteCode::MovEnv, ByteCode::SetR, ByteCode::SetDP, ByteCode::CloseN, ByteCode::AllocI, @@ -128,7 +128,7 @@ constexpr ByteCode bcCommands[bcCommandNumber] = ByteCode::Shl, ByteCode::Shr, ByteCode::XLabelDPR, ByteCode::TryLock, ByteCode::FreeLock, ByteCode::XQuit, ByteCode::ExtCloseN, ByteCode::XCmpSI, ByteCode::LoadSI, ByteCode::XFSave, ByteCode::XSaveN, ByteCode::XSaveDispN, ByteCode::XStoreFIR, ByteCode::LNeg, ByteCode::Parent, - ByteCode::LLoadSI + ByteCode::LLoadSI, ByteCode::PeekTLS, ByteCode::StoreTLS }; void elena_lang :: writeCoreReference(JITCompilerScope* scope, ref_t reference, @@ -619,6 +619,39 @@ void elena_lang :: loadNOp(JITCompilerScope* scope) writer->seekEOF(); } +void elena_lang :: loadTLSOp(JITCompilerScope* scope) +{ + MemoryWriter* writer = scope->codeWriter; + + void* code = scope->compiler->_inlines[0][scope->code()]; + + pos_t position = writer->position(); + pos_t length = *(pos_t*)((char*)code - sizeof(pos_t)); + + // simply copy correspondent inline code + writer->write(code, length); + + // resolve section references + pos_t count = *(pos_t*)((char*)code + length); + RelocationEntry* entries = (RelocationEntry*)((char*)code + length + sizeof(pos_t)); + while (count > 0) { + // locate relocation position + writer->seek(position + entries->offset); + switch (entries->reference) { + case ARG32_1: + scope->compiler->writeArgAddress(scope, scope->command.arg1, 0, mskOffset32); + break; + default: + writeCoreReference(scope, entries->reference, entries->offset, code); + break; + } + + entries++; + count--; + } + writer->seekEOF(); +} + void elena_lang :: loadFieldIndexOp(JITCompilerScope* scope) { MemoryWriter* writer = scope->codeWriter; @@ -3034,6 +3067,14 @@ addr_t JITCompiler :: allocateTLSIndex(ReferenceHelperBase* helper, MemoryWriter return position; } +pos_t JITCompiler :: getTLSSize(MemoryBase* tlsSection) +{ + if (tlsSection->length() > sizeof(ThreadContent)) { + return tlsSection->length() - sizeof(ThreadContent); + } + return 0; +} + void JITCompiler :: allocateThreadContent(MemoryWriter* tlsWriter) { ThreadContent content = {}; @@ -3506,7 +3547,7 @@ void JITCompiler32 :: writeVariable(MemoryWriter& writer) writer.writeDWord(0); } -void JITCompiler32 :: updateEnvironment(MemoryBase* rdata, pos_t staticCounter, bool virtualMode) +void JITCompiler32 :: updateEnvironment(MemoryBase* rdata, pos_t staticCounter, pos_t tlsSize, bool virtualMode) { void* env = _preloaded.get(SYSTEM_ENV); if (virtualMode) { @@ -3514,12 +3555,15 @@ void JITCompiler32 :: updateEnvironment(MemoryBase* rdata, pos_t staticCounter, int64_t tmp = (int64_t)env; MemoryBase::writeDWord(rdata, (static_cast(tmp) & ~mskAnyRef), staticCounter); + MemoryBase::writeDWord(rdata, (static_cast(tmp) & ~mskAnyRef), tlsSize); #else MemoryBase::writeDWord(rdata, ((ref_t)env & ~mskAnyRef), staticCounter); + MemoryBase::writeDWord(rdata, ((ref_t)env & ~mskAnyRef) + 4, tlsSize); #endif } else { - *(int*)env = staticCounter; + ((int*)env)[0] = staticCounter; + ((int*)env)[1] = tlsSize; } } @@ -3978,14 +4022,16 @@ void JITCompiler64 :: writeVariable(MemoryWriter& writer) writer.writeQWord(0); } -void JITCompiler64 :: updateEnvironment(MemoryBase* rdata, pos_t staticCounter, bool virtualMode) +void JITCompiler64 :: updateEnvironment(MemoryBase* rdata, pos_t staticCounter, pos_t tlsSize, bool virtualMode) { void* env = _preloaded.get(SYSTEM_ENV); if (virtualMode) { MemoryBase::writeQWord(rdata, (int64_t)env & ~mskAnyRef, staticCounter); + MemoryBase::writeQWord(rdata, (int64_t)env & ~mskAnyRef + 8, tlsSize); } else { - *(int64_t*)env = staticCounter; + ((int64_t*)env)[0] = staticCounter; + ((int64_t*)env)[1] = tlsSize; } } diff --git a/elenasrc3/engine/jitcompiler.h b/elenasrc3/engine/jitcompiler.h index 598603c2a..ac9612344 100644 --- a/elenasrc3/engine/jitcompiler.h +++ b/elenasrc3/engine/jitcompiler.h @@ -109,6 +109,7 @@ namespace elena_lang friend void loadLOp(JITCompilerScope* scope); friend void loadIndexOp(JITCompilerScope* scope); friend void loadNOp(JITCompilerScope* scope); + friend void loadTLSOp(JITCompilerScope* scope); friend void loadFieldIndexOp(JITCompilerScope* scope); friend void loadStackIndexOp(JITCompilerScope* scope); friend void loadArgIndexOp(JITCompilerScope* scope); @@ -221,6 +222,7 @@ namespace elena_lang addr_t allocateTLSIndex(ReferenceHelperBase* helper, MemoryWriter& writer) override; void allocateThreadContent(MemoryWriter* tlsWriter) override; + pos_t getTLSSize(MemoryBase* tlsSection) override; void* getSystemEnv() override; @@ -304,7 +306,7 @@ namespace elena_lang void writeAttribute(MemoryWriter& writer, int category, ustr_t value, addr_t address, bool virtualMode) override; - void updateEnvironment(MemoryBase* rdata, pos_t staticCounter, bool virtualMode) override; + void updateEnvironment(MemoryBase* rdata, pos_t staticCounter, pos_t tlsSize, bool virtualMode) override; void updateVoidObject(MemoryBase* rdata, addr_t superAddress, bool virtualMode) override; void allocateVariable(MemoryWriter& writer) override; @@ -383,7 +385,7 @@ namespace elena_lang void writeAttribute(MemoryWriter& writer, int category, ustr_t value, addr_t address, bool virtualMode) override; - void updateEnvironment(MemoryBase* rdata, pos_t staticCounter, bool virtualMode) override; + void updateEnvironment(MemoryBase* rdata, pos_t staticCounter, pos_t tlsSize, bool virtualMode) override; void updateVoidObject(MemoryBase* rdata, addr_t superAddress, bool virtualMode) override; void allocateVariable(MemoryWriter& writer) override; @@ -413,6 +415,7 @@ namespace elena_lang void loadLOp(JITCompilerScope* scope); void loadIndexOp(JITCompilerScope* scope); void loadNOp(JITCompilerScope* scope); + void loadTLSOp(JITCompilerScope* scope); void loadFieldIndexOp(JITCompilerScope* scope); void loadVMTIndexOp(JITCompilerScope* scope); void loadFrameIndexOp(JITCompilerScope* scope); diff --git a/elenasrc3/engine/jitlinker.cpp b/elenasrc3/engine/jitlinker.cpp index 856703738..f919436cc 100644 --- a/elenasrc3/engine/jitlinker.cpp +++ b/elenasrc3/engine/jitlinker.cpp @@ -21,6 +21,12 @@ constexpr ref_t SIGNATURE_MASK = 0x80000000; // --- JITLinkerReferenceHelper --- +inline void writeVOffset32(MemoryBase* image, pos_t position, addr_t vaddress, pos_t disp) +{ + vaddress += disp; + image->write(position, &vaddress, 4); +} + inline void writeVAddress32(MemoryBase* image, pos_t position, addr_t vaddress, pos_t disp, ref_t addressMask, bool virtualMode) { @@ -340,6 +346,9 @@ void JITLinker::JITLinkerReferenceHelper :: writeReference(MemoryBase& target, p case mskRef32Lo: ::writeRef32Lo(_owner->_compiler, &target, position, vaddress, disp, addressMask, _owner->_virtualMode); break; + case mskOffset32: + ::writeVOffset32(&target, position, vaddress, disp); + break; default: // to make compiler happy break; @@ -495,6 +504,13 @@ addr_t JITLinker :: calculateVAddress(MemoryWriter& writer, ref_t targetMask) return _virtualMode ? (writer.position() | targetMask) : (addr_t)writer.address(); } +addr_t JITLinker :: calculateVOffset(MemoryWriter& writer, ref_t targetMask) +{ + // align the section + _compiler->alignCode(writer, _alignment, (targetMask & mskImageType) == mskCodeRef); + + return writer.position(); +} void JITLinker :: fixOffset(pos_t position, ref_t offsetMask, int offset, MemoryBase* image) { MemoryWriter writer(image); @@ -554,15 +570,6 @@ void JITLinker :: fixReferences(VAddressMap& relocations, MemoryBase* image) case mskExtMssgLiteralRef: vaddress = resolve({ info.module, info.module->resolveConstant(currentRef) }, currentMask, false); break; - //case mskNameLiteralRef: - //case mskPathLiteralRef: - // //NOTE : Zero reference is considered to be the reference to itself - // if (currentRef) { - // vaddress = resolveName(_loader->retrieveReferenceInfo(info.module, currentRef, - // currentMask, _forwardResolver), currentMask == mskPathLiteralRef); - // } - // else vaddress = resolveName(ownerReferenceInfo, currentMask == mskPathLiteralRef); - // break; default: vaddress = resolve(_loader->retrieveReferenceInfo(info.module, currentRef, currentMask, _forwardResolver), currentMask, false); @@ -597,6 +604,9 @@ void JITLinker :: fixReferences(VAddressMap& relocations, MemoryBase* image) case mskRef32Lo: ::writeRef32Lo(_compiler, image, it.key(), vaddress, info.disp, info.addressMask, _virtualMode); break; + case mskOffset32: + ::writeVOffset32(image, it.key(), vaddress, info.disp); + break; default: // to make compiler happy break; @@ -1489,6 +1499,20 @@ addr_t JITLinker :: resolveStaticVariable(ReferenceInfo referenceInfo, ref_t sec return vaddress; } +addr_t JITLinker :: resolveThreadVariable(ReferenceInfo referenceInfo, ref_t sectionMask) +{ + // get target image & resolve virtual address + MemoryBase* image = _imageProvider->getTargetSection(mskTLSRef); + MemoryWriter writer(image); + + addr_t offset = calculateVOffset(writer, mskTLSRef); + _compiler->writeVariable(writer); + + _mapper->mapReference(referenceInfo, offset, sectionMask); + + return offset; +} + addr_t JITLinker :: resolveDistributeCategory(ReferenceInfo referenceInfo, ref_t sectionMask) { ReferenceProperName name(referenceInfo.referenceName); @@ -1659,6 +1683,7 @@ void JITLinker :: complete(JITCompilerBase* compiler, ustr_t superClass) compiler->updateEnvironment( _imageProvider->getRDataSection(), compiler->getStaticCounter(_imageProvider->getStatSection(), true), + compiler->getTLSSize(_imageProvider->getTLSSection()), _virtualMode); fixReferences(mbReferences, mbSection); @@ -1714,6 +1739,9 @@ addr_t JITLinker :: resolve(ReferenceInfo referenceInfo, ref_t sectionMask, bool case mskStaticVariable: address = resolveStaticVariable(referenceInfo, sectionMask); break; + case mskTLSVariable: + address = resolveThreadVariable(referenceInfo, sectionMask); + break; case mskTypeListRef: address = resolveMetaSection(referenceInfo, sectionMask, _loader->getSection(referenceInfo, sectionMask, 0, silentMode)); diff --git a/elenasrc3/engine/jitlinker.h b/elenasrc3/engine/jitlinker.h index f4226563c..7db73adcb 100644 --- a/elenasrc3/engine/jitlinker.h +++ b/elenasrc3/engine/jitlinker.h @@ -174,6 +174,7 @@ namespace elena_lang bool _withDebugInfo; addr_t calculateVAddress(MemoryWriter& writer, ref_t targetMask); + addr_t calculateVOffset(MemoryWriter& writer, ref_t targetMask); addr_t getVMTAddress(ModuleBase* module, ref_t reference, VAddressMap& references); void* getVMTPtr(addr_t address); @@ -215,6 +216,7 @@ namespace elena_lang addr_t resolveConstantArray(ReferenceInfo referenceInfo, ref_t sectionMask, bool silentMode); addr_t resolveConstantDump(ReferenceInfo referenceInfo, ref_t sectionMask, bool silentMode); addr_t resolveStaticVariable(ReferenceInfo referenceInfo, ref_t sectionMask); + addr_t resolveThreadVariable(ReferenceInfo referenceInfo, ref_t sectionMask); addr_t resolveName(ReferenceInfo referenceInfo, bool onlyPath); addr_t resolvePackage(ReferenceInfo referenceInfo); addr_t resolveRawConstant(ReferenceInfo referenceInfo); diff --git a/elenasrc3/engine/langcommon.h b/elenasrc3/engine/langcommon.h index 3355dfd62..2a16a1597 100644 --- a/elenasrc3/engine/langcommon.h +++ b/elenasrc3/engine/langcommon.h @@ -352,6 +352,7 @@ namespace elena_lang constexpr auto errInvalidFile = 205; constexpr auto errInvalidParserTarget = 206; constexpr auto errInvalidParserTargetType = 207; + constexpr auto errTLSIsNotAllowed = 208; constexpr auto errInvalidModuleVersion = 210; constexpr auto errEmptyTarget = 212; @@ -489,6 +490,7 @@ namespace elena_lang constexpr auto V_WEAK = 0x80001029u; constexpr auto V_INTERFACE_DISPATCHER = 0x8000102Au; constexpr auto V_PACKED_STRUCT = 0x8000102Cu; + constexpr auto V_THREADVAR = 0x8000102Du; /// primitive type attribute constexpr auto V_STRINGOBJ = 0x80000801u; diff --git a/elenasrc3/engine/syntaxtree.h b/elenasrc3/engine/syntaxtree.h index dd28c23ef..0267ebde6 100644 --- a/elenasrc3/engine/syntaxtree.h +++ b/elenasrc3/engine/syntaxtree.h @@ -209,6 +209,7 @@ namespace elena_lang EnumNameArgParameter = 0x000113, EnumArgParameter = 0x000114, NillableInfo = 0x000115, + HasStaticConstructor = 0x000116, Column = 0x000201, Row = 0x000202, diff --git a/elenasrc3/engine/windows/winroutines.cpp b/elenasrc3/engine/windows/winroutines.cpp index ff2de46cc..e9f9e2247 100644 --- a/elenasrc3/engine/windows/winroutines.cpp +++ b/elenasrc3/engine/windows/winroutines.cpp @@ -62,11 +62,11 @@ uintptr_t SystemRoutineProvider :: ExpandPerm(void* allocPtr, size_t newSize) return !r ? 0 : (uintptr_t)allocPtr; } -void* SystemRoutineProvider :: CreateThread(size_t tt_index, int flags, void* threadProc) +void* SystemRoutineProvider :: CreateThread(size_t tt_index, int stackSize, int flags, void* threadProc) { return ::CreateThread( nullptr, // default security attributes - 0, // use default stack size + stackSize, // use default stack size (LPTHREAD_START_ROUTINE)threadProc, // thread function name (LPVOID)tt_index, // argument to thread function flags, // use default creation flags diff --git a/elenasrc3/engine/x86helper.h b/elenasrc3/engine/x86helper.h index 8b5bbe768..9431eb7c9 100644 --- a/elenasrc3/engine/x86helper.h +++ b/elenasrc3/engine/x86helper.h @@ -115,7 +115,8 @@ namespace elena_lang enum class SegmentPrefix : unsigned int { None = 0, - FS = 0x64 + FS = 0x64, + GS = 0x65 }; // --- X86JumpType --- @@ -302,6 +303,11 @@ namespace elena_lang static void writeModRM(MemoryWriter& writer, X86Operand sour, X86Operand dest) { int prefix = ((unsigned int)dest.type & 0x300) >> 2; + // HOTFIX : to allow GS M64Disp32 + if (prefix == 0x80 && dest.prefix == SegmentPrefix::GS) { + writer.writeByte(0x14); + prefix = 0x10; + } int opcode = prefix + ((char)sour.type << 3) + (char)dest.type; writer.writeByte((unsigned char)opcode); diff --git a/elenasrc3/engine/x86relocation.h b/elenasrc3/engine/x86relocation.h index f1e2f1379..77271c40e 100644 --- a/elenasrc3/engine/x86relocation.h +++ b/elenasrc3/engine/x86relocation.h @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Compiler // // This header contains relocation functions -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- using namespace elena_lang; @@ -72,6 +72,9 @@ inline void relocate64(pos_t pos, ref_t mask, ref_t reference, void* address, Ad case mskDataRef64: *(unsigned long long*)address += (unsigned long long)(base + space->data); break; + case mskTLSRef64: + *(unsigned long long*)address += (unsigned long long)(base + space->tls); + break; case mskStatDataRef64: *(unsigned long long*)address += (unsigned long long)(base + space->stat); break; diff --git a/elenasrc3/ide/idecontroller.cpp b/elenasrc3/ide/idecontroller.cpp index c49ad0472..230168c7d 100644 --- a/elenasrc3/ide/idecontroller.cpp +++ b/elenasrc3/ide/idecontroller.cpp @@ -896,10 +896,17 @@ void ProjectController :: includeFile(ProjectModel& model, path_t filePath) PathString relPath(filePath); _pathHelper->makePathRelative(relPath, *model.projectPath); - model.sources.add((*relPath).clone()); - model.addedSources.add((*relPath).clone()); + // HOTFIX : make sure the file is not included + if (model.sources.retrieveIndex(*relPath, [](path_t arg, path_t current) + { + return current.compare(arg); + }) == -1) + { + model.sources.add((*relPath).clone()); + model.addedSources.add((*relPath).clone()); - model.notSaved = true; + model.notSaved = true; + } } void ProjectController :: excludeFile(ProjectModel& model, path_t filePath) diff --git a/elenasrc3/ide/ideversion.h b/elenasrc3/ide/ideversion.h index 5128be75a..4849cb291 100644 --- a/elenasrc3/ide/ideversion.h +++ b/elenasrc3/ide/ideversion.h @@ -1,2 +1,2 @@ -#define IDE_REVISION_NUMBER 14 +#define IDE_REVISION_NUMBER 15 diff --git a/elenasrc3/ide/windows/winide.cpp b/elenasrc3/ide/windows/winide.cpp index 9a51743c7..3e0cf3871 100644 --- a/elenasrc3/ide/windows/winide.cpp +++ b/elenasrc3/ide/windows/winide.cpp @@ -626,7 +626,6 @@ void IDEWindow :: updateCompileMenu(bool compileEnable, bool debugEnable, bool s { enableMenuItemById(IDM_PROJECT_COMPILE, compileEnable, false); enableMenuItemById(IDM_PROJECT_OPTION, compileEnable, false); - enableMenuItemById(IDM_PROJECT_INCLUDE, compileEnable, false); enableMenuItemById(IDM_DEBUG_RUN, debugEnable, true); enableMenuItemById(IDM_DEBUG_STEPINTO, debugEnable, true); diff --git a/elenasrc3/tools/asmc/asmconst.h b/elenasrc3/tools/asmc/asmconst.h index 43c246a3b..fcbf4ede5 100644 --- a/elenasrc3/tools/asmc/asmconst.h +++ b/elenasrc3/tools/asmc/asmconst.h @@ -12,7 +12,7 @@ namespace elena_lang { - #define ASM_REVISION_NUMBER 0x0003 + #define ASM_REVISION_NUMBER 0x0005 constexpr auto N_ARGUMENT1 = "__n_1"; constexpr auto N_ARGUMENT2 = "__n_2"; diff --git a/elenasrc3/tools/asmc/x86assembler.cpp b/elenasrc3/tools/asmc/x86assembler.cpp index 6e5851885..4216a94d4 100644 --- a/elenasrc3/tools/asmc/x86assembler.cpp +++ b/elenasrc3/tools/asmc/x86assembler.cpp @@ -519,6 +519,15 @@ X86Operand X86Assembler :: compileOperand(ScriptToken& tokenInfo, ustr_t errorMe } else operand.prefix = SegmentPrefix::FS; } + else if (tokenInfo.compare("gs")) { + read(tokenInfo, ":", ASM_DOUBLECOLON_EXPECTED); + operand = readPtrOperand(tokenInfo, X86OperandType::M64disp32, errorMessage); + + if (operand.prefix != SegmentPrefix::None) { + throw SyntaxError(ASM_SYNTAXERROR, tokenInfo.lineInfo); + } + else operand.prefix = SegmentPrefix::GS; + } else { operand = defineOperand(tokenInfo, X86OperandType::DD, errorMessage); if (operand.type != X86OperandType::Unknown) { @@ -3147,6 +3156,11 @@ bool X86_64Assembler::compileAdd(X86Operand source, X86Operand target, MemoryWri writer.writeByte(0x01); X86Helper::writeModRM(writer, target, source); } + else if (source.isRX64() && target.isR64()) { + writer.writeByte(0x4C); + writer.writeByte(0x01); + X86Helper::writeModRM(writer, target, source); + } else return X86Assembler::compileAdd(source, target, writer); return true; @@ -3340,6 +3354,10 @@ bool X86_64Assembler :: compileLea(X86Operand source, X86Operand target, MemoryW bool X86_64Assembler :: compileMov(X86Operand source, X86Operand target, MemoryWriter& writer) { + if (target.prefix == SegmentPrefix::GS) { + writer.writeByte(0x65); + } + if (source.isRX64() && target.isDB_DD_DQ()) { target.type = X86OperandType::DQ; writer.writeByte(0x49); @@ -3451,6 +3469,10 @@ bool X86_64Assembler :: compilePush(X86Operand source, MemoryWriter& writer) writer.writeByte(0x41); writer.writeByte(0x50 + (char)source.type); } + else if (source.isM64()) { + writer.writeByte(0xFF); + X86Helper::writeModRM(writer, { X86OperandType::R32 + 6 }, source); + } else if (source.type == X86OperandType::DB) { writer.writeByte(0x6A); writer.writeByte(source.offset); @@ -3486,6 +3508,12 @@ bool X86_64Assembler :: compileShl(X86Operand source, X86Operand target, MemoryW X86Helper::writeModRM(writer, X86Operand(X86OperandType::R32 + 4), source); writer.writeByte(target.offset); } + else if (source.isRX64() && target.type == X86OperandType::DB) { + writer.writeByte(0x4C); + writer.writeByte(0xC1); + X86Helper::writeModRM(writer, X86Operand(X86OperandType::R32 + 4), source); + writer.writeByte(target.offset); + } else if (source.isR64() && target.type == X86OperandType::CL) { writer.writeByte(0x48); writer.writeByte(0xD3); @@ -3606,3 +3634,21 @@ bool X86_64Assembler :: compileMOpCode(ScriptToken& tokenInfo, MemoryWriter& wri } else return X86Assembler::compileMOpCode(tokenInfo, writer); } + +bool X86_64Assembler :: compileXadd(X86Operand source, X86Operand target, MemoryWriter& writer, PrefixInfo& prefixScope) +{ + if (test(prefixScope.value, LOCK_PREFIX)) { + writer.writeByte(0xF0); + + prefixScope.value &= ~LOCK_PREFIX; + } + + if (source.isM64() && target.isR32()) { + writer.writeByte(0x0F); + writer.writeByte(0xC0); + X86Helper::writeModRM(writer, target, source); + } + else return X86Assembler::compileXadd(source, target, writer, prefixScope); + + return true; +} diff --git a/elenasrc3/tools/asmc/x86assembler.h b/elenasrc3/tools/asmc/x86assembler.h index f5ae9f446..b9ff795c1 100644 --- a/elenasrc3/tools/asmc/x86assembler.h +++ b/elenasrc3/tools/asmc/x86assembler.h @@ -284,6 +284,7 @@ namespace elena_lang bool compileShl(X86Operand source, X86Operand target, MemoryWriter& writer) override; bool compileSub(X86Operand source, X86Operand target, MemoryWriter& writer) override; bool compileTest(X86Operand source, X86Operand target, MemoryWriter& writer) override; + bool compileXadd(X86Operand source, X86Operand target, MemoryWriter& writer, PrefixInfo& prefixScope) override; bool compileXor(X86Operand source, X86Operand target, MemoryWriter& writer) override; bool compileMOpCode(ScriptToken& tokenInfo, MemoryWriter& writer) override; diff --git a/elenasrc3/tools/ecv/ecviewer.cpp b/elenasrc3/tools/ecv/ecviewer.cpp index 1e2fbab14..7b92525e7 100644 --- a/elenasrc3/tools/ecv/ecviewer.cpp +++ b/elenasrc3/tools/ecv/ecviewer.cpp @@ -287,6 +287,9 @@ void ByteCodeViewer :: addRArg(arg_t arg, IdentifierString& commandStr, bool wit case mskStaticVariable: appendPrefix(commandStr, "static:", withTabbing); break; + case mskTLSVariable: + appendPrefix(commandStr, "threadvar:", withTabbing); + break; case mskProcedureRef: appendPrefix(commandStr, "procedure:", withTabbing); break; diff --git a/elenasrc3/tools/ldoc/ldoc.cpp b/elenasrc3/tools/ldoc/ldoc.cpp index e5a3e50e8..15f797430 100644 --- a/elenasrc3/tools/ldoc/ldoc.cpp +++ b/elenasrc3/tools/ldoc/ldoc.cpp @@ -172,65 +172,6 @@ void parseNs(IdentifierString& ns, ustr_t root, ustr_t fullName) ns.append(fullName, last); } -//bool parseTemplateType(IdentifierString& line, size_t index, bool argMode) -//{ -// IdentifierString temp(line); -// -// line.truncate(0); -// -// size_t last = index; -// bool first = true; -// bool noCurlybrackets = false; -// bool nsExpected = true; -// if (argMode && (*temp).startsWith(ByRefPrefix)) { -// // HOTFIX : recognize byref argument -// -// temp.cut(0, getlength(ByRefPrefix)); -// -// line.append("ref "); -// noCurlybrackets = true; -// } -// else if ((*temp).startsWith(ArrayPrefix)) { -// // HOTFIX : recognize array argument -// temp.cut(0, getlength(ArrayPrefix)); -// -// line.append("arrayof "); -// noCurlybrackets = true; -// nsExpected = false; -// } -// -// for (size_t i = index; i < temp.length(); i++) { -// if (temp[i] == '@') { -// temp[i] = '\''; -// } -// else if (temp[i] == '#') { -// line.append((*temp) + last + 1, i - last - 1); -// } -// else if (temp[i] == '&') { -// if (first) { -// last = i; -// line.append("<"); -// first = false; -// } -// else { -// line.append((*temp) + last + 1, i - last - 1); -// line.append(','); -// last = i; -// } -// } -// } -// -// if (noCurlybrackets) { -// line.append(*temp); -// } -// else { -// line.append((*temp) + last + 1); -// line.append(">"); -// } -// -// return nsExpected; -//} - inline bool isTemplateArg(ustr_t name, size_t index) { size_t endPos = name.findSub(index, '&', name.length()); diff --git a/elenasrc3/tools/ldoc/ldocconst.h b/elenasrc3/tools/ldoc/ldocconst.h index 65719cc93..957aa5da1 100644 --- a/elenasrc3/tools/ldoc/ldocconst.h +++ b/elenasrc3/tools/ldoc/ldocconst.h @@ -19,8 +19,8 @@ namespace elena_lang constexpr auto LDOC_MODULE_NOTLOADED = "cannot load a module: %s"; - constexpr auto TITLE = "ELENA Standard Library 6.0: Module "; - constexpr auto TITLE2 = "ELENA Standard Library
    6.0"; + constexpr auto TITLE = "ELENA Standard Library 6.3: Module "; + constexpr auto TITLE2 = "ELENA Standard Library
    6.3"; } diff --git a/examples60/threads/threadpool/sample1.l b/examples60/threads/threadpool/sample1.l new file mode 100644 index 000000000..1f422417a --- /dev/null +++ b/examples60/threads/threadpool/sample1.l @@ -0,0 +1,24 @@ +import system'threading; +import extensions'threading; + +WorkItem1(state) +{ + console.writeLine($"WorkItem1: {state}"); +} + +WorkItem2(state) +{ + int num := state.toInt(); + int square := num * num; + console.writeLine($"WorkItem2: {num} * {num} = {square}"); +} + +public sample1() +{ + ThreadPool.queueAction(&WorkItem1, "Hello"); + ThreadPool.queueAction(&WorkItem2, 42); + + Thread.sleep(1000); + + console.writeLine("Main thread exits") +} \ No newline at end of file diff --git a/examples60/threads/threadpool/threadpool.l b/examples60/threads/threadpool/threadpool.l new file mode 100644 index 000000000..eadd1f919 --- /dev/null +++ b/examples60/threads/threadpool/threadpool.l @@ -0,0 +1,9 @@ +import extensions; + +public program() +{ + int solution := program_arguments.getAtOrDefault(1, "1").toInt(); + + solution => + 1 { sample1() } +} \ No newline at end of file diff --git a/examples60/threads/threadpool/threadpoolsamples.prj b/examples60/threads/threadpool/threadpoolsamples.prj new file mode 100644 index 000000000..4cf92a207 --- /dev/null +++ b/examples60/threads/threadpool/threadpoolsamples.prj @@ -0,0 +1,14 @@ + + + + sample1.l + threadpool.l + + + + threadpoolsamples + + threadpoolsamples + + + \ No newline at end of file diff --git a/recompile60.bat b/recompile60.bat index e17ef34e2..b8a304ab1 100644 --- a/recompile60.bat +++ b/recompile60.bat @@ -17,29 +17,28 @@ REM /m:2 is used to build using parallel compilation "%InstallDir%\MSBuild\Current\Bin\MSBuild.exe" elenasrc3\elenasrc3.sln /p:configuration=release /p:Platform="x86" /m:2 IF NOT %ERRORLEVEL%==0 GOTO CompilerError -ECHO Generating data files required for tests +ECHO Generating data files ECHO ---------------------------------------- -bin\sg-cli dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO SGDataGenError -@echo on - -move dat\sg\syntax60.dat bin - -bin\og-cli -s dat\og\bt_rules60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO BTDataGenError -@echo on -move dat\og\bt_rules60.dat bin +CALL build\rebuild_data60_x86.bat +IF NOT %ERRORLEVEL%==0 GOTO CompilerError -bin\elena-tests.exe +ECHO Unit tests +ECHO ---------------------------------------- +bin\elena-tests-x86.exe IF NOT %ERRORLEVEL%==0 GOTO CompilerError REM /m:2 is used to build using parallel compilation "%InstallDir%\MSBuild\Current\Bin\MSBuild.exe" elenasrc3\elenasrc3.sln /p:configuration=release /p:Platform="x64" /m:2 IF NOT %ERRORLEVEL%==0 GOTO CompilerError -bin\elena-tests64.exe +ECHO Generating data files +ECHO ---------------------------------------- +CALL build\rebuild_data60_x64.bat +IF NOT %ERRORLEVEL%==0 GOTO CompilerError + +ECHO Unit tests +ECHO ---------------------------------------- +bin\elena-tests-x64.exe IF NOT %ERRORLEVEL%==0 GOTO CompilerError ECHO =========== Release Compiled ================== diff --git a/src60/core/system.core_routines.esm b/src60/core/system.core_routines.esm index 9736bd2ef..177bcfc3f 100644 --- a/src60/core/system.core_routines.esm +++ b/src60/core/system.core_routines.esm @@ -1284,6 +1284,11 @@ procedure __copySubStr2 (self, dest, index, len, sour) open (2),[],[i1,i2,tmp] + peek fp:len + load + cmp n:0 + jeq labEnd + peek fp:index load save dp:i2 @@ -1312,6 +1317,7 @@ labNext: xcmp dp:i1 jne labNext +labEnd: close [] end @@ -2085,7 +2091,7 @@ labSkip: end -procedure __thread_create(self,arg,flags,ptr) +procedure __thread_create(self,arg,flags,stackSize,ptr) xflush sp:0 xflush sp:1 @@ -2098,6 +2104,7 @@ procedure __thread_create(self,arg,flags,ptr) call extern:CreateThreadLA ( *arg, procedure:"system'core_routines'thread_start", + *stackSize, *flags) system 7 @@ -2812,6 +2819,7 @@ procedure thread_start(index) unhook // ; == enter GC critical section == + snop system 6 call extern:UninitThreadLA ( diff --git a/src60/extensions/basic.l b/src60/extensions/basic.l index 20a2eacac..9d645c256 100644 --- a/src60/extensions/basic.l +++ b/src60/extensions/basic.l @@ -105,3 +105,16 @@ public sealed class LongInteger : BaseVariable, Reference } } +// ---- objectExOp --- + +public extension objectExOp +{ + getAtOrDefault(int index, default) + { + if (self.Length > index) { + ^ self.getAt(index) ?? default; + }; + + ^ default + } +} \ No newline at end of file diff --git a/src60/extensions/tests.l b/src60/extensions/tests.l index 547f891a1..cdd7709ea 100644 --- a/src60/extensions/tests.l +++ b/src60/extensions/tests.l @@ -12,8 +12,7 @@ public singleton Assert { ifnot(val == expr) { - AssertException.raise("Assertion failed: expected {0} -was {1}".interpolate(val, expr)) + AssertException.raise("Assertion failed: expected '{0}' was '{1}'".interpolate(val, expr)) } } @@ -27,7 +26,19 @@ was {1}".interpolate(val, expr)) }; Assert.ifTrue(failed); - } + } + + ifNotFailed(Func f) + { + var failed := true; + f() \\ + on::(e) + { + failed := false; + }; + + Assert.ifTrue(failed); + } ifTrue(b) { diff --git a/src60/extensions/threading/threading.l b/src60/extensions/threading/threading.l index 7f0a9bb57..f1f1a4e08 100644 --- a/src60/extensions/threading/threading.l +++ b/src60/extensions/threading/threading.l @@ -15,6 +15,6 @@ public singleton threadControl sleep (int n) { - @system'threading'threadControl.sleep(n) + Thread.sleep(n) } } diff --git a/src60/system/attributes/attributes.l b/src60/system/attributes/attributes.l index 213dc31c6..ee70714ef 100644 --- a/src60/system/attributes/attributes.l +++ b/src60/system/attributes/attributes.l @@ -65,7 +65,7 @@ #let attributes["template"] := 80001027h; #let attributes["weak"] := 80001029h; #let attributes["packed"] := 8000102Ch; - +#let attributes["__threadvar"] := 8000102Dh; /// primitive types #let attributes["__string"] := 80000801h; diff --git a/src60/system/collections/threadsafe/queues.l b/src60/system/collections/threadsafe/queues.l new file mode 100644 index 000000000..942fe5675 --- /dev/null +++ b/src60/system/collections/threadsafe/queues.l @@ -0,0 +1,113 @@ +import system; +import system'collections; + +// --- Queue Template --- + +public sealed ThreadsafeQueue +{ + object _sync; + + List _array; + Reference _top; + Reference _tale; + + constructor() + { + _sync := new object(); + + _array := new List(8); + _top := 0; + _tale := 0; + } + + int Length + { + get() + { + int n := 0; + + lock(_sync) { + int top := *_top; + int tale := *_tale; + + n := tale - top; + }; + + ^ n + } + } + + push(T object) + { + lock(_sync) { + int capacity := _array.Length; + int tale := *_tale; + + if (tale < capacity) + { + _array.setAt(tale, object) + } + else + { + _array.append(object) + }; + + _tale.append(1) + } + } + + T pop() + { + + lock(_sync) { + int top := *_top; + int tale := *_tale; + + if (tale == top) + { InvalidOperationException.new("Queue is empty").raise() }; + + T item := _array.at(top); + + _top.append(1); + + // reuse the space if the queue is empty + if(tale == top) + { + _top.Value := 0; + _tale.Value := 0 + }; + + ^ item + } + } + + get Queue Snapshot() + : info("Returns a copy of the queue") + { + int top := 0; + int tale := 0; + List copy := nil; + + lock(_sync) { + top := *_top; + tale := *_tale; + copy := _array.clone(); + }; + + var Queue q := new Queue(); + for (int i := top; i <= tale; i++) { + q.push(copy[i]); + }; + + ^ q + } + + clear() + { + lock(_sync) { + _array.clear(); + _top.Value :=0; + _tale.Value:=0 + } + } +} diff --git a/src60/system/collections/threadsafe/template_tests.l b/src60/system/collections/threadsafe/template_tests.l new file mode 100644 index 000000000..cf9a2e9e5 --- /dev/null +++ b/src60/system/collections/threadsafe/template_tests.l @@ -0,0 +1,7 @@ + +T1; + +threadsafe_collections_template_test() +{ + ThreadsafeQueue o3 := nil; +} diff --git a/src60/system/pointers.l b/src60/system/pointers.l index f03332fbc..73dde6774 100644 --- a/src60/system/pointers.l +++ b/src60/system/pointers.l @@ -52,7 +52,10 @@ public sealed const struct UnsafePointer constructor(object obj) { - self.assignPtr(obj); + if (obj :is pointer) { + _pointer := cast UnsafePointer(obj) + } + else self.assignPtr(obj); } get constructor Default() diff --git a/src60/system/primitives.l b/src60/system/primitives.l index 36f55ac93..60a9b69e5 100644 --- a/src60/system/primitives.l +++ b/src60/system/primitives.l @@ -277,7 +277,7 @@ internal singleton PrimitiveRealOperations } } -/*internal*/public singleton PrimitiveStringOperations +internal singleton PrimitiveStringOperations { copy(byte[] dest, int srcIndex, int size, string sour) : external(system'core_routines'__copySubStr); copyTo(byte[] dest, int dstIndex, int size, string sour) : external(system'core_routines'__copySubStr2); diff --git a/src60/system/runtime/common.l b/src60/system/runtime/common.l index bab8ada64..d0bcce2d8 100644 --- a/src60/system/runtime/common.l +++ b/src60/system/runtime/common.l @@ -1,5 +1,7 @@ import system; +// --- Package --- + public class Package { string Namespace : rprop; @@ -28,4 +30,8 @@ public extension commonOp ^ new Package(ptr); } -} \ No newline at end of file +} + +// --- ProcessorType --- + +public const struct ProcessorType : enum(x86 ::= 0, AMD64 ::= 1, ARM ::= 2, ARM64 ::= 2, IA64 ::= 3, Unknown ::= 255); diff --git a/src60/system/runtime/env.l b/src60/system/runtime/env.l new file mode 100644 index 000000000..65b4e2046 --- /dev/null +++ b/src60/system/runtime/env.l @@ -0,0 +1,16 @@ +import system; + +public singleton Environment +{ + int ProcessorCount + { + get() + = systemInfo.ProcessorCount; + } + + ProcessorType ProcessorType + { + get() + = systemInfo.ProcessorType; + } +} diff --git a/src60/system/runtime/win32_env.l b/src60/system/runtime/win32_env.l new file mode 100644 index 000000000..62012b590 --- /dev/null +++ b/src60/system/runtime/win32_env.l @@ -0,0 +1,59 @@ +import system; + +public const int PROCESSOR_ARCHITECTURE_AMD64 = 9; +public const int PROCESSOR_ARCHITECTURE_ARM = 5; +public const int PROCESSOR_ARCHITECTURE_ARM64 = 12; +public const int PROCESSOR_ARCHITECTURE_IA64 = 6; +public const int PROCESSOR_ARCHITECTURE_INTEL = 0; +public const int PROCESSOR_ARCHITECTURE_UNKNOWN = 65535; + +struct SYSTEM_INFO +{ + int dwOemId : prop; + int dwPageSize : prop; + pointer lpMinimumApplicationAddress : prop; + pointer lpMaximumApplicationAddress : prop; + pointer dwActiveProcessorMask : prop; + int dwNumberOfProcessors : prop; + int dwProcessorType : prop; + int dwAllocationGranularity : prop; + short wProcessorLevel : prop; + short wProcessorRevision : prop; +} + +internal class SystemInfo +{ + int ProcessorCount : rprop; + ProcessorType ProcessorType : rprop; + + private ProcessorType toProcessorType(int cpuType) + { + if (cpuType == PROCESSOR_ARCHITECTURE_AMD64) + { ^ class ProcessorType.AMD64 } + else if (cpuType == PROCESSOR_ARCHITECTURE_ARM) + { ^ class ProcessorType.ARM } + else if (cpuType == PROCESSOR_ARCHITECTURE_ARM64) + { ^ class ProcessorType.ARM64 } + else if (cpuType == PROCESSOR_ARCHITECTURE_IA64) + { ^ class ProcessorType.IA64 } + else if (cpuType == PROCESSOR_ARCHITECTURE_INTEL) + { ^ class ProcessorType.x86 }; + + ^ class ProcessorType.Unknown + } + + constructor() + { + SYSTEM_INFO si := default; + + extern { + extern KERNEL32.GetSystemInfo(si); + }; + + ProcessorType := toProcessorType(si.dwOemId); + ProcessorCount := si.dwNumberOfProcessors; + } +} + +internal static SystemInfo systemInfo + = new SystemInfo(); \ No newline at end of file diff --git a/src60/system/system.prj b/src60/system/system.prj index 9300576ee..40c049af5 100644 --- a/src60/system/system.prj +++ b/src60/system/system.prj @@ -80,6 +80,10 @@ io\win_files.l io\win_getfiles.l + + collections\threadsafe\queues.l + collections\threadsafe\template_tests.l + routines\enumerables.l routines\patterns.l @@ -93,10 +97,16 @@ runtime\common.l runtime\gc_routines.l runtime\vectortable.l + runtime\win32_env.l + runtime\env.l + threading\common.l threading\win32_handlers.l threading\thread.l + threading\win32_semaphores.l + threading\blockinglists.l + threading\threadpool.l dynamic\reflection.l diff --git a/src60/system/threading/blockinglists.l b/src60/system/threading/blockinglists.l new file mode 100644 index 000000000..efdb3935e --- /dev/null +++ b/src60/system/threading/blockinglists.l @@ -0,0 +1,27 @@ +import system; +import system'collections'threadsafe; + +public sealed class BlockingQueue +{ + ThreadsafeQueue _list := new ThreadsafeQueue(); + Semaphore _semaphore; + + constructor() + { + _semaphore := Semaphore.create(0, IntNumber.MaxValue); + } + + push(T value) + { + _semaphore.release(); + + _list.push(value); + } + + T pop() + { + _semaphore.wait(); + + ^ _list.pop(); + } +} \ No newline at end of file diff --git a/src60/system/threading/common.l b/src60/system/threading/common.l new file mode 100644 index 000000000..eaa1624ec --- /dev/null +++ b/src60/system/threading/common.l @@ -0,0 +1,3 @@ +import system; + +public const struct ThreadPriority : enum(Lowest ::= 0, BelowNormal ::= 1, Normal ::= 2, AboveNormal ::= 3, Highest ::= 4); \ No newline at end of file diff --git a/src60/system/threading/thread.l b/src60/system/threading/thread.l index a7d4a28f3..e0f405e02 100644 --- a/src60/system/threading/thread.l +++ b/src60/system/threading/thread.l @@ -1,19 +1,133 @@ import system; +// --- StartHelper --- + +internal sealed class StartHelper : interface +{ + Func1 f; + + constructor(Func1 f) + { + this f := f + } + + constructor(Func1 f, object arg) + { + this f := f; + Argument := arg + } + + object Argument : prop; + + function() + { + f(Argument) + } +} + // --- Thread --- public sealed class Thread { - ThreadHandle _handle; + __threadvar Thread _currentThread; + + ThreadHandle _handle; + object _startArg; constructor assign(Func f) { _handle := new ThreadHandle(f); } - start() => _handle; + constructor assign(Func f, int stackSize) + { + _handle := new ThreadHandle(f, stackSize); + } + + constructor assign(Func1 f) + { + _startArg := new StartHelper(f); + _handle := new ThreadHandle(_startArg); + } + + constructor assign(Func1 f, int stackSize) + { + _startArg := new StartHelper(f); + _handle := new ThreadHandle(_startArg, stackSize); + } + + internal constructor current() + { + _handle := new ThreadHandle(); + } + + private static getCurrentThread() + { + _currentThread := Thread.current(); + + ^ _currentThread + } + + static Thread Current + { + get() + = _currentThread ?? getCurrentThread(); + } + + ThreadPriority Priority + { + get() + = _handle.getPriority(); + + set(value) + { + _handle.setPriority(value); + } + } + + bool IsAlive + = _handle.checkIfAlive(); + + start() + { + if (handle.isNil()) + InvalidOperationException.raise(); + + ifnot (_startArg.isNil()) + InvalidOperationException.raise(); + + _handle.start(); + } + + start(object arg) + { + if (handle.isNil()) + InvalidOperationException.raise(); + + if (_startArg.isNil()) + InvalidOperationException.raise(); + + _startArg.Argument := arg; + + _handle.start(); + } join() => _handle; - close() => _handle; + join(int milliseconds) => _handle; + + close() + { + if (handle.isNil()) + InvalidOperationException.raise(); + + _handle.close(); + + _handle := nil; + } + + static sleep(int milliseconds) + { + ThreadHandle.sleep(milliseconds) + } } \ No newline at end of file diff --git a/src60/system/threading/threadpool.l b/src60/system/threading/threadpool.l new file mode 100644 index 000000000..93ec94b2f --- /dev/null +++ b/src60/system/threading/threadpool.l @@ -0,0 +1,35 @@ +import system; +import system'collections'threadsafe; +import system'runtime; + +public sealed class ThreadPool +{ + private constructor() {} + + static BlockingQueue _actions := new BlockingQueue(); + + static constructor() + { + int cpuCount := Environment.ProcessorCount; + for(int i := 0; i < cpuCount; i++) { + Thread.assign( + { + while (true) { + Func f := _actions.pop(); + + f(); + } + }); + } + } + + static queueAction(Func f) + { + _actions.push(f); + } + + static queueAction(Func1 f, object arg) + { + _actions.push(new StartHelper(f, arg)); + } +} \ No newline at end of file diff --git a/src60/system/threading/win32_handlers.l b/src60/system/threading/win32_handlers.l index 27b29dd9d..f9477ec5f 100644 --- a/src60/system/threading/win32_handlers.l +++ b/src60/system/threading/win32_handlers.l @@ -3,25 +3,96 @@ import system'runtime; public const int INFINITE = 0FFFFFFFFh; +public const int WAIT_TIMEOUT = 00000102h; +public const int WAIT_OBJECT_0 = 0; + +public const int THREAD_PRIORITY_HIGHEST = 2; +public const int THREAD_PRIORITY_ABOVE_NORMAL = 1; +public const int THREAD_PRIORITY_NORMAL = 0; +public const int THREAD_PRIORITY_BELOW_NORMAL = -1; +public const int THREAD_PRIORITY_LOWEST = -2; + // --- ThreadHandle --- public sealed struct ThreadHandle { Handle _handle; pointer _actionPtr; - private handle createThreadHandle(pointer arg, int flags) : external(system'core_routines'__thread_create); + private handle createThreadHandle(pointer arg, int flags, int stackSafe) : external(system'core_routines'__thread_create); + + private ThreadPriority toPriority(int win_priority) + { + if (win_priority == THREAD_PRIORITY_HIGHEST) + { ^ ThreadPriority.Highest } + else if (win_priority == THREAD_PRIORITY_ABOVE_NORMAL) + { ^ ThreadPriority.AboveNormal } + else if (win_priority == THREAD_PRIORITY_NORMAL) + { ^ ThreadPriority.Normal } + else if (win_priority == THREAD_PRIORITY_BELOW_NORMAL) + { ^ ThreadPriority.BelowNormal } + else if (win_priority == THREAD_PRIORITY_LOWEST) + { ^ ThreadPriority.Lowest }; + + ^ ThreadPriority.Lowest + } + + private int fromPriority(ThreadPriority priority) + { + if (priority == THREAD_PRIORITY_HIGHEST) + { ^ ThreadPriority.Highest } + else if (priority == THREAD_PRIORITY_ABOVE_NORMAL) + { ^ ThreadPriority.AboveNormal } + else if (priority == THREAD_PRIORITY_NORMAL) + { ^ ThreadPriority.Normal } + else if (priority == ThreadPriority.BelowNormal) + { ^ THREAD_PRIORITY_BELOW_NORMAL } + else if (priority == ThreadPriority.Lowest) + { ^ THREAD_PRIORITY_LOWEST }; + + ^ THREAD_PRIORITY_LOWEST + } - constructor(Func f) + constructor() + { + _handle := extern KERNEL32.GetCurrentThread(); + } + + constructor(object f) { _actionPtr := PermVectorTable.allocate(f); - _handle := self.createThreadHandle(_actionPtr, 4); + _handle := self.createThreadHandle(_actionPtr, 4, 0); if (_handle.isUnassigned()) { InvalidOperationException.raise(); } } + constructor(object f, int stackSize) + { + _actionPtr := PermVectorTable.allocate(f); + + _handle := self.createThreadHandle(_actionPtr, 4, stackSize); + + if (_handle.isUnassigned()) { + InvalidOperationException.raise(); + } + } + + ThreadPriority getPriority() + { + int win_priority := extern KERNEL32.GetThreadPriority(_handle); + + ^ toPriority(win_priority); + } + + setPriority(ThreadPriority priority) + { + int win_priority := fromPriority(priority); + + extern KERNEL32.SetThreadPriority(_handle, win_priority); + } + start() { extern KERNEL32.ResumeThread(_handle) @@ -34,16 +105,20 @@ public sealed struct ThreadHandle { extern KERNEL32.WaitForSingleObject(_handle, timeOut) } - + + bool checkIfAlive() + { + int retVal := extern KERNEL32.WaitForSingleObject(_handle, 0); + + ^ retVal == WAIT_TIMEOUT; + } + close() { extern KERNEL32.CloseHandle(_handle) } -} -public singleton threadControl -{ - sleep(int interval) + static sleep(int interval) { extern { diff --git a/src60/system/threading/win32_semaphores.l b/src60/system/threading/win32_semaphores.l new file mode 100644 index 000000000..3f927f2fc --- /dev/null +++ b/src60/system/threading/win32_semaphores.l @@ -0,0 +1,29 @@ +import system; + +public struct Semaphore +{ + Handle _handle; + + constructor create(int initValue, int maxValue) + { + _handle := extern KERNEL32.CreateSemaphoreA(0, initValue, maxValue, 0); + } + + close() + { + extern KERNEL32.CloseHandle(_handle) + } + + wait() + { + extern + { + extern KERNEL32.WaitForSingleObject(_handle, INFINITE); + } + } + + release() + { + extern KERNEL32.ReleaseSemaphore(_handle, 1, 0); + } +} \ No newline at end of file diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index b0e0cff04..87874ece0 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -1,33 +1,22 @@ import extensions; +import system'collections; -singleton IteratorEnumerable : Enumerable +public sealed class QList { - Enumerator enumerator() - = IteratorEnumerable.infinitEnumerator(); + List _list := new List(); - yield Enumerator infinitEnumerator() + constructor() {} + + push(T o) { - $yield 2; - $yield 5; - $yield 7; + _list.append(o); } } -public iteratorMethodTest() -{ - auto e := IteratorEnumerable.enumerator(); - - Assert.ifTrue(e.next()); - Assert.ifTrue(*e == 2); - Assert.ifTrue(e.next()); - Assert.ifTrue(*e == 5); - Assert.ifTrue(e.next()); - Assert.ifTrue(*e == 7); - Assert.ifFalse(e.next()); -} - - public program() { - iteratorMethodTest(); + QList l := new QList(); + + l.push(1); + l.push(2); } diff --git a/tests60/system_tests/basic.l b/tests60/system_tests/basic.l index 511b58284..9622be4ed 100644 --- a/tests60/system_tests/basic.l +++ b/tests60/system_tests/basic.l @@ -2002,7 +2002,7 @@ public ifNilOperatorTest() : testCase() // --- enumTest --- -public const struct Color : enum(Red = 1,Green = 2,Blue = 3); +public const struct Color : enum(Red ::= 1,Green ::= 2,Blue ::= 3); public enumTest() : testCase() { @@ -2075,6 +2075,11 @@ public stringInterpolation() : testCase() Assert.ifEqual(s,"a_1_b_2_c"); console.write("."); + + var s2 := $"{ 3 }_b_{ 4 }_c"; + + Assert.ifEqual(s2,"3_b_4_c"); + console.write("."); } // --- iteratorMethodTest --- @@ -2105,3 +2110,17 @@ public iteratorMethodTest() : testCase() Assert.ifFalse(e.next()); console.write("."); } + +public isNilOperatorTest() : testCase() +{ + var a := nil; + var b := 2; + + var r := a ?? b; + Assert.ifTrue(r == 2); + console.write("."); + + Assert.ifNotFailed({ var a := new A(); var b := nil; var r := a ?? b.test() }); + Assert.ifFailed({ var a := nil; var b := nil; var r := a ?? b.test() }); + console.write("."); +}