Skip to content

Conversation

@Mr-Rm
Copy link
Collaborator

@Mr-Rm Mr-Rm commented Dec 25, 2025

Поскольку имена свойств, методов, полей структур являются по определению корректными идентификаторами, их можно хранить в отдельном от произвольных констант списке в виде строк, а не преобразовывать в IValue и обратно.
То же относится и именам типов и классов.

Summary by CodeRabbit

  • New Features

    • Module dump output now includes an identifiers section for clearer visibility into compiled modules.
  • Refactor

    • Unified identifier handling across compilation and runtime for more consistent lookups and instance creation.
    • Internal collections made more concrete to simplify initialization and use.
  • Style

    • Numerous small conditional and initialization refinements for consistency and readability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 25, 2025

📝 Walkthrough

Walkthrough

Adds identifier interning: compiler now emits identifier indices instead of embedding constant strings; runtime resolves names via module.Identifiers; ModuleDumpWriter prints a new ".identifiers" section. Many collection emptiness checks changed from > 0/Any() to != 0/Count across the codebase.

Changes

Cohort / File(s) Summary
Identifier System Foundation
src/ScriptEngine/Machine/StackRuntimeModule.cs
Introduces Identifiers (List<string>); Code, VariableRefs, MethodRefs narrowed to concrete List<T> types.
Code Generation for Identifiers
src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
Adds GetIdentNumber(string) helper; emits identifier indices in place of constant-name pushes for Resolve/ResolveProp/ResolveMethod and object/type creation; several Count > 0Count != 0 changes.
Runtime Name Resolution & Instance Creation
src/ScriptEngine/Machine/MachineInstance.cs
Resolves properties/types via _module.Identifiers[arg]; refactors NewInstance/NewFunc to use CreateInstance(typeName, args); various emptiness checks switched to Count != 0.
Module Dump Output
src/ScriptEngine/Compiler/ModuleDumpWriter.cs
WriteImage now emits a ".identifiers" section listing each identifier with its index after constants.
Style/Conditional Normalization (many files)
src/OneScript.Core/..., src/OneScript.Language/..., src/OneScript.Native/..., src/OneScript.StandardLibrary/..., src/oscript/Web/...
Numerous Count > 0 / Any() checks replaced with Count != 0 or Count == 0 predicates; no substantive behavioral changes expected.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Generator as CodeGenerator
  participant Module as StackRuntimeModule
  participant Runtime as MachineInstance
  participant Dumper as ModuleDumpWriter

  rect rgb(230,245,255)
  Note over Generator,Module: Compile-time identifier interning
  Generator->>Module: GetIdentNumber("foo")
  activate Module
  Module-->>Generator: identIndex (adds "foo" if missing)
  deactivate Module
  Generator->>Module: Emit command referencing identIndex
  end

  rect rgb(245,255,230)
  Note over Runtime,Module: Runtime resolution
  Runtime->>Module: fetch Identifiers[identIndex]
  Module-->>Runtime: "foo"
  Runtime->>Runtime: resolve property/method/type by name
  end

  rect rgb(255,245,230)
  Note over Dumper,Module: Dumping module
  Dumper->>Module: Read Constants, then Identifiers
  Module-->>Dumper: list of identifier strings
  Dumper->>Dumper: emit ".identifiers" section
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested reviewers

  • EvilBeaver

Poem

🐰 I hop through lists and bind each name,
I tuck them in an index, tidy as a game.
From compiler's nib to runtime's den,
I whisper names so calls find when.
Hooray — small hops, big tidy zen. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective: refactoring to store property and method names in a separate identifier list instead of converting them to/from IValue, which is reflected across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a13d2fe and 3262cf9.

📒 Files selected for processing (3)
  • src/OneScript.Core/Contexts/ClassBuilder.cs
  • src/ScriptEngine/Machine/MachineInstance.cs
  • src/oscript/Web/Multipart/BinaryStreamStack.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/oscript/Web/Multipart/BinaryStreamStack.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.cursor/rules/langversion.mdc)

Do not use C# language features that are not available in C# 8 when generating code for projects using .NET 8.0 with LangVersion 8

Files:

  • src/OneScript.Core/Contexts/ClassBuilder.cs
  • src/ScriptEngine/Machine/MachineInstance.cs
🧠 Learnings (2)
📚 Learning: 2024-07-25T09:44:11.960Z
Learnt from: EvilBeaver
Repo: EvilBeaver/OneScript PR: 1426
File: src/OneScript.Web.Server/HeaderDictionaryWrapper.cs:43-50
Timestamp: 2024-07-25T09:44:11.960Z
Learning: The `CanWrite` attribute in the `ContextProperty` attribute is used for different purposes and is not related to the presence of a setter in the property.

Applied to files:

  • src/OneScript.Core/Contexts/ClassBuilder.cs
📚 Learning: 2025-12-18T16:13:05.448Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1636
File: src/OneScript.StandardLibrary/StringOperations.cs:155-157
Timestamp: 2025-12-18T16:13:05.448Z
Learning: Guideline: In OneScript, when a method parameter has a concrete type (e.g., string) and is called from scripts with omitted arguments, the runtime passes an empty string "" rather than null. Direct (non-script) calls to the method may still pass null, so implement defensive null checks for these parameters in public methods that can be called from scripts. Treat empty string as a legitimate value for script calls, and explicitly handle null for direct calls (e.g., fail fast, throw ArgumentNullException, or normalize to "" where appropriate). This should apply to all C# methods that may be invoked from OneScript with optional string parameters across the codebase.

Applied to files:

  • src/OneScript.Core/Contexts/ClassBuilder.cs
  • src/ScriptEngine/Machine/MachineInstance.cs
🧬 Code graph analysis (2)
src/OneScript.Core/Contexts/ClassBuilder.cs (2)
src/OneScript.Core/Contexts/ContextPropertyInfo.cs (2)
  • GetCustomAttributes (34-37)
  • GetCustomAttributes (39-42)
src/OneScript.Core/Contexts/AnnotationHolder.cs (2)
  • GetCustomAttributes (23-26)
  • GetCustomAttributes (28-31)
src/ScriptEngine/Machine/MachineInstance.cs (2)
src/ScriptEngine/Machine/Contexts/ScriptDrivenObject.cs (4)
  • IValue (147-152)
  • IValue (185-188)
  • IValue (215-218)
  • IValue (300-311)
src/ScriptEngine/Machine/DefaultTypeManager.cs (2)
  • TryGetType (59-63)
  • TryGetType (65-75)
🔇 Additional comments (8)
src/OneScript.Core/Contexts/ClassBuilder.cs (1)

114-117: Previous issue resolved: deprecation filtering now implemented.

The method now correctly filters deprecated properties based on the includeDeprecations parameter, matching the pattern in MarkedAsContextMethod. The parameter type refinement from MemberInfo to PropertyInfo also improves type safety. This addresses the concern raised in the previous review.

src/ScriptEngine/Machine/MachineInstance.cs (7)

1009-1020: LGTM! Identifier interning optimization applied correctly.

The change from _module.Constants[arg].ToString(_process) to _module.Identifiers[arg] eliminates unnecessary string conversions for property name resolution, aligning with the PR's goal to optimize identifier handling.


1044-1097: LGTM! Consistent identifier interning for method resolution.

Method name resolution now uses _module.Identifiers[arg], matching the pattern applied to property resolution and avoiding redundant string conversions.


1131-1149: LGTM! More explicit emptiness check.

The change from Count > 0 to Count != 0 is semantically equivalent and provides a more explicit check for exception stack emptiness.


1183-1198: LGTM! Well-structured refactoring with identifier interning.

The refactored NewInstance method now:

  • Derives argCount from the stack (consistent with method call patterns)
  • Resolves type names via _module.Identifiers[arg] (identifier interning optimization)
  • Delegates activation to the new CreateInstance helper (promotes code reuse)

The stack manipulation is correct and aligns with the broader identifier-based refactor.


1248-1258: LGTM! Consistent emptiness check pattern.

Matches the explicit Count != 0 pattern used elsewhere in the exception handling flow.


1369-1405: LGTM! Performance optimization avoiding LINQ overhead.

The change from !module.Methods.Any() to module.Methods.Count == 0 eliminates unnecessary LINQ enumeration overhead, providing a more efficient O(1) check.


2369-2406: LGTM! Excellent refactoring to eliminate code duplication.

The introduction of CreateInstance as a shared helper encapsulates the type activation pattern and promotes code reuse between:

  • NewInstance: uses compile-time identifier from _module.Identifiers[arg]
  • NewFunc: uses runtime type name from stack parameter

The TODO comment on line 2397 appropriately acknowledges the temporary cast to TypeFactory pending future refactoring. The activation logic is clear and correct.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs (1)

1324-1336: Consider case-insensitive identifier matching.

The GetIdentNumber helper uses List<string>.IndexOf which performs case-sensitive comparison. However, OneScript identifiers are typically case-insensitive. If the same property/method is referenced with different casing (e.g., MyProp vs myProp), they would be stored as separate entries.

Verify whether case-insensitive matching is required here. If so, consider using FindIndex with a case-insensitive comparer:

🔎 Suggested fix for case-insensitive matching
 private int GetIdentNumber(string ident)
 {
-    
-    var idx = _module.Identifiers.IndexOf(ident);
+    var idx = _module.Identifiers.FindIndex(x => 
+        string.Equals(x, ident, StringComparison.OrdinalIgnoreCase));
     if (idx < 0)
     {
         idx = _module.Identifiers.Count;
         _module.Identifiers.Add(ident);
     }
     return idx;
 }

Also, minor formatting nit: there's an extra blank line at line 1326 inside the method body.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e7de3a and 4ba9eb7.

📒 Files selected for processing (4)
  • src/ScriptEngine/Compiler/ModuleDumpWriter.cs
  • src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
  • src/ScriptEngine/Machine/MachineInstance.cs
  • src/ScriptEngine/Machine/StackRuntimeModule.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.cursor/rules/langversion.mdc)

Do not use C# language features that are not available in C# 8 when generating code for projects using .NET 8.0 with LangVersion 8

Files:

  • src/ScriptEngine/Machine/MachineInstance.cs
  • src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
  • src/ScriptEngine/Compiler/ModuleDumpWriter.cs
  • src/ScriptEngine/Machine/StackRuntimeModule.cs
🧠 Learnings (1)
📚 Learning: 2025-12-18T16:13:05.448Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1636
File: src/OneScript.StandardLibrary/StringOperations.cs:155-157
Timestamp: 2025-12-18T16:13:05.448Z
Learning: Guideline: In OneScript, when a method parameter has a concrete type (e.g., string) and is called from scripts with omitted arguments, the runtime passes an empty string "" rather than null. Direct (non-script) calls to the method may still pass null, so implement defensive null checks for these parameters in public methods that can be called from scripts. Treat empty string as a legitimate value for script calls, and explicitly handle null for direct calls (e.g., fail fast, throw ArgumentNullException, or normalize to "" where appropriate). This should apply to all C# methods that may be invoked from OneScript with optional string parameters across the codebase.

Applied to files:

  • src/ScriptEngine/Machine/MachineInstance.cs
  • src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
  • src/ScriptEngine/Compiler/ModuleDumpWriter.cs
  • src/ScriptEngine/Machine/StackRuntimeModule.cs
🧬 Code graph analysis (1)
src/ScriptEngine/Machine/MachineInstance.cs (6)
src/OneScript.Core/Values/BslDateValue.cs (1)
  • ToString (61-64)
src/OneScript.Core/Contexts/Variable.cs (2)
  • ToString (150-153)
  • ToString (163-166)
src/ScriptEngine/Machine/Contexts/UserScriptContextInstance.cs (1)
  • ToString (110-113)
src/OneScript.Core/Values/BslBooleanValue.cs (1)
  • ToString (53-56)
src/OneScript.Core/Values/BslValue.cs (1)
  • ToString (25-28)
src/ScriptEngine/Machine/Contexts/ContextIValueImpl.cs (1)
  • ToString (41-44)
🔇 Additional comments (8)
src/ScriptEngine/Compiler/ModuleDumpWriter.cs (1)

132-138: LGTM!

The new .identifiers section is well-structured and consistent with the existing dump format for constants. The output formatting aligns with the established style of the dump writer.

src/ScriptEngine/Machine/MachineInstance.cs (3)

679-684: LGTM!

Minor formatting adjustment with no functional impact.


1014-1014: LGTM!

The identifier-based resolution correctly uses the new Identifiers list for property and method name lookup. This eliminates the unnecessary string-to-IValue-to-string conversions, achieving the PR's optimization goal.

Also applies to: 1051-1051


1194-1194: Verify the simplified ToString() call for type name resolution.

The change from PopRawBslValue().ToString(_process) to _operationStack.Pop().ToString() relies on code generation always pushing a BslStringValue. While this should work for the static new case (as indicated by the comment), consider whether:

  1. The value could be an IVariable wrapper requiring dereferencing via RawValue()
  2. Any edge cases exist where ToString(_process) would produce different results than ToString()

Based on the relevant code snippets showing BslValue.ToString(IBslProcess) defaults to ToString(), this appears safe for string values, but worth confirming there are no scenarios where the stack contains a reference type here.

src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs (3)

492-492: LGTM!

The explicit count check (node.Children.Count != 0) is clearer and consistent with the pattern used in VisitReturnNode at line 480.


731-736: LGTM!

The method resolution now correctly uses identifier-based lookup via GetIdentNumber, which stores method names in the dedicated Identifiers list instead of the constants pool.


739-742: LGTM!

Property resolution now uses the identifier table, consistent with the method resolution changes.

src/ScriptEngine/Machine/StackRuntimeModule.cs (1)

29-34: The Code property at line 57 is not part of the IExecutableModule interface contract—the interface does not define a Code member. Therefore, typing it as List<Command> does not create interface compatibility issues. The property is implementation-specific to StackRuntimeModule and can safely use the concrete List<T> type.

The use of List<T> for the internal properties Identifiers, VariableRefs, and MethodRefs is appropriate since these are internal members and enables efficient operations like IndexOf.

Likely an incorrect or invalid review comment.

@Mr-Rm Mr-Rm marked this pull request as draft December 25, 2025 15:19
@Mr-Rm Mr-Rm marked this pull request as ready for review December 25, 2025 18:00
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/ScriptEngine/Machine/MachineInstance.cs (1)

27-27: Remove unused import directive.

The using System.Dynamic; directive appears unused in this file—there are no references to dynamic types or DLR infrastructure.

Proposed cleanup
-using System.Dynamic;
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ba9eb7 and a13d2fe.

📒 Files selected for processing (12)
  • src/OneScript.Core/Contexts/ClassBuilder.cs
  • src/OneScript.Language/SyntaxAnalysis/BslSyntaxWalker.cs
  • src/OneScript.Language/SyntaxAnalysis/ConditionalDirectiveHandler.cs
  • src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs
  • src/OneScript.Native/Compiler/MethodCompiler.cs
  • src/OneScript.Native/Compiler/StatementBlocksWriter.cs
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
  • src/OneScript.StandardLibrary/CustomLineFeedStreamReader.cs
  • src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs
  • src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
  • src/ScriptEngine/Machine/MachineInstance.cs
  • src/oscript/Web/Multipart/BinaryStreamStack.cs
✅ Files skipped from review due to trivial changes (3)
  • src/OneScript.Language/SyntaxAnalysis/BslSyntaxWalker.cs
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
  • src/OneScript.Language/SyntaxAnalysis/ConditionalDirectiveHandler.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.cursor/rules/langversion.mdc)

Do not use C# language features that are not available in C# 8 when generating code for projects using .NET 8.0 with LangVersion 8

Files:

  • src/OneScript.StandardLibrary/CustomLineFeedStreamReader.cs
  • src/OneScript.Core/Contexts/ClassBuilder.cs
  • src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs
  • src/OneScript.Native/Compiler/MethodCompiler.cs
  • src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs
  • src/oscript/Web/Multipart/BinaryStreamStack.cs
  • src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
  • src/ScriptEngine/Machine/MachineInstance.cs
  • src/OneScript.Native/Compiler/StatementBlocksWriter.cs
🧠 Learnings (3)
📚 Learning: 2025-12-18T16:13:05.448Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1636
File: src/OneScript.StandardLibrary/StringOperations.cs:155-157
Timestamp: 2025-12-18T16:13:05.448Z
Learning: Guideline: In OneScript, when a method parameter has a concrete type (e.g., string) and is called from scripts with omitted arguments, the runtime passes an empty string "" rather than null. Direct (non-script) calls to the method may still pass null, so implement defensive null checks for these parameters in public methods that can be called from scripts. Treat empty string as a legitimate value for script calls, and explicitly handle null for direct calls (e.g., fail fast, throw ArgumentNullException, or normalize to "" where appropriate). This should apply to all C# methods that may be invoked from OneScript with optional string parameters across the codebase.

Applied to files:

  • src/OneScript.StandardLibrary/CustomLineFeedStreamReader.cs
  • src/OneScript.Core/Contexts/ClassBuilder.cs
  • src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs
  • src/OneScript.Native/Compiler/MethodCompiler.cs
  • src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs
  • src/oscript/Web/Multipart/BinaryStreamStack.cs
  • src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
  • src/ScriptEngine/Machine/MachineInstance.cs
  • src/OneScript.Native/Compiler/StatementBlocksWriter.cs
📚 Learning: 2024-07-25T09:44:11.960Z
Learnt from: EvilBeaver
Repo: EvilBeaver/OneScript PR: 1426
File: src/OneScript.Web.Server/HeaderDictionaryWrapper.cs:43-50
Timestamp: 2024-07-25T09:44:11.960Z
Learning: The `CanWrite` attribute in the `ContextProperty` attribute is used for different purposes and is not related to the presence of a setter in the property.

Applied to files:

  • src/OneScript.Core/Contexts/ClassBuilder.cs
📚 Learning: 2025-09-04T11:15:14.305Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1578
File: src/ScriptEngine/Machine/GenericIValueComparer.cs:55-64
Timestamp: 2025-09-04T11:15:14.305Z
Learning: In OneScript, all objects that implement `IValue` are descendants of `BslValue`, making casting from `IValue` to `BslValue` type-safe.

Applied to files:

  • src/ScriptEngine/Machine/MachineInstance.cs
🧬 Code graph analysis (3)
src/OneScript.Core/Contexts/ClassBuilder.cs (3)
src/OneScript.Core/Contexts/ContextPropertyInfo.cs (2)
  • GetCustomAttributes (34-37)
  • GetCustomAttributes (39-42)
src/OneScript.Core/Contexts/ContextMethodInfo.cs (2)
  • GetCustomAttributes (48-51)
  • GetCustomAttributes (53-56)
src/OneScript.Core/Contexts/AnnotationHolder.cs (2)
  • GetCustomAttributes (23-26)
  • GetCustomAttributes (28-31)
src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs (1)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (1)
  • Count (135-138)
src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs (8)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs (2)
  • Count (27-27)
  • Count (29-29)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (1)
  • Count (122-122)
src/OneScript.StandardLibrary/Collections/ValueTree/ValueTreeRow.cs (2)
  • Count (38-41)
  • Count (43-43)
src/ScriptEngine/Machine/Contexts/EnumerationContext.cs (1)
  • Count (113-116)
src/OneScript.StandardLibrary/Collections/ValueTree/ValueTreeColumnCollection.cs (1)
  • Count (93-93)
src/OneScript.StandardLibrary/Collections/StructureImpl.cs (1)
  • Count (206-206)
src/OneScript.StandardLibrary/Collections/FixedStructureImpl.cs (1)
  • Count (136-136)
src/ScriptEngine/Machine/Contexts/AutoCollectionContext.cs (2)
  • Count (28-28)
  • Count (30-30)
🔇 Additional comments (23)
src/OneScript.StandardLibrary/CustomLineFeedStreamReader.cs (1)

59-59: LGTM! Consistency improvement.

The change from > 0 to != 0 is functionally equivalent and aligns with the project-wide pattern for count checks.

src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs (1)

123-123: LGTM! Micro-optimization aligns with PR objectives.

The change from Any() to Count != 0 avoids LINQ enumeration overhead while maintaining identical semantics. Since failedTasks is a List<T>, the Count property access is O(1).

src/OneScript.Native/Compiler/StatementBlocksWriter.cs (1)

21-21: LGTM! Micro-optimization applied consistently.

The change from Count > 0 to Count != 0 is functionally equivalent and aligns with the micro-optimization pattern applied throughout this PR.

src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs (2)

126-126: LGTM: Collection emptiness check normalized.

The change from !Any() to Count == 0 is semantically equivalent and aligns with the broader repository pattern of normalizing collection checks.


1653-1653: LGTM: Non-emptiness check normalized.

The change from Count > 0 to Count != 0 is semantically equivalent for the stack's non-negative count and follows the repository-wide pattern.

src/OneScript.Native/Compiler/MethodCompiler.cs (4)

716-733: LGTM: Stack emptiness checks are correct.

The changes from Count > 0 to Count != 0 are semantically equivalent and align with the PR's micro-optimization objectives.


1147-1153: LGTM: Children count check is correct.

The emptiness check for the argument's children collection is correct and consistent with the PR's optimization pattern.


1416-1419: LGTM: Argument children check is correct.

The collection emptiness check is correct, properly distinguishing between passed and omitted arguments.


1525-1528: LGTM: Constructor argument check is correct.

The children count check correctly handles both provided and omitted constructor arguments.

src/oscript/Web/Multipart/BinaryStreamStack.cs (4)

91-94: LGTM: Efficient collection emptiness check.

Replacing Any() with Count != 0 eliminates LINQ overhead and is more idiomatic for Stack<T>.


185-185: LGTM: Consistent optimization.

The loop condition correctly uses Count != 0, aligning with the NextStream() implementation and avoiding LINQ overhead.


231-231: LGTM: Consistent optimization.

The loop condition correctly uses Count != 0, matching the pattern in the Read(byte[], int, int) overload.


399-399: LGTM: Consistent optimization.

The ternary expression correctly uses Count != 0, aligning with the overall refactoring pattern in this file.

src/ScriptEngine/Machine/MachineInstance.cs (6)

1010-1021: LGTM: Identifier-based property resolution.

The change from constant-based to identifier-based property name resolution is correct and aligns with the PR's optimization goal.


1045-1098: LGTM: Identifier-based method name resolution.

The change from constant-based to identifier-based method name resolution is correct and consistent with the broader refactoring.


1132-1150: LGTM: More idiomatic count check.

The change from Count > 0 to Count != 0 is more idiomatic for collection emptiness checks.


1370-1406: LGTM: More efficient collection check.

The change from !module.Methods.Any() to module.Methods.Count == 0 is more efficient—it avoids allocating an enumerator.


2370-2407: LGTM: Well-refactored type instantiation logic.

The extraction of CreateInstance centralizes type lookup and factory activation logic, making it reusable for both NewFunc and NewInstance.


1184-1199: Stack protocol for NewInstance opcode is correctly implemented.

The compiler's MakeNewObjectStatic flow always emits ArgNum before NewInstance:

  • Via PushCallArguments for cases with arguments
  • Via explicit AddCommand(OperationCode.ArgNum, 0) for no-argument cases

The refactored NewInstance method correctly consumes this protocol: it pops the argument count from the stack (Line 1186) and receives the identifier index as the arg parameter (Line 1196).

src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs (4)

720-736: LGTM: Identifier-based method resolution.

The change to emit identifier indices for ResolveMethodFunc and ResolveMethodProc is correct and aligns with the runtime changes in MachineInstance.cs.


738-741: LGTM: Identifier-based property resolution.

The change to emit identifier indices for ResolveProp is correct and consistent with the broader refactoring.


1063-1076: LGTM: Stack protocol matches runtime changes.

The MakeNewObjectStatic refactoring correctly emits the stack protocol expected by MachineInstance.NewInstance:

  • PushCallArguments pushes arguments and then ArgNum (count on stack)
  • NewInstance opcode takes identifier index as argument and pops count from stack

1321-1330: LGTM: Identifier interning implementation.

The GetIdentNumber method correctly implements identifier interning by maintaining a deduplicated list in _module.Identifiers. The implementation follows the same pattern as GetConstNumber.

@Mr-Rm
Copy link
Collaborator Author

Mr-Rm commented Dec 25, 2025

Замечание про ClassBuilder.MarkedAsContextProperty - будто действительно баг?

@EvilBeaver
Copy link
Owner

Замечание про ClassBuilder.MarkedAsContextProperty - будто действительно баг?

Надо уточнить места вызовов, чтобы клиентский код получил тот же ответ. А так да, похоже на баг

@EvilBeaver
Copy link
Owner

@Mr-Rm а есть цифры, насколько стало быстрее? Просто любопытно

@Mr-Rm
Copy link
Collaborator Author

Mr-Rm commented Dec 26, 2025

Замечание про ClassBuilder.MarkedAsContextProperty - будто действительно баг?

Надо уточнить места вызовов, чтобы клиентский код получил тот же ответ. А так да, похоже на баг

Вызов только из одного места, по умолчанию includeDeprecations = false, но оно не учитывалось никак

@Mr-Rm
Copy link
Collaborator Author

Mr-Rm commented Dec 26, 2025

По цифрам: по сравнению с rc-10, с изменениями последних четырех PR время запуска oneunit сократилось с 2.1 до 1.8 секунд, winow - c 2.6 до 2.3 (оба без параметров). Но основное время съедает загрузка библиотек: их насчитал 44 с 272 классами в oneunit и 40 с 303 классами в winow. Тут уже нужно ускорять работу package-loader'а.
Но в движке резерв ещё есть, и по мелочам, и по крупному. Например, можно вернуть operator precedence парсер вместо recursive descend. Или, радикальнее, сделать native режим без строгой типизации.

@EvilBeaver EvilBeaver merged commit b1b9a15 into EvilBeaver:develop Dec 26, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants