Inline the 320-line codegen_variable_node() function directly into the
codegen() function to eliminate function call overhead for every
variable-sized AST node processing.
Co-authored-by: Claude <noreply@anthropic.com>
Remove useless outer switch statement and convert nested if-else chain to
a clean switch statement on node types. This improves code readability
and maintainability in the parser's block handling logic.
Key improvements:
- Replace outer switch with simple early return for non-NODE_VARIABLE cases
- Convert if-else if chain to proper switch statement on var_type
- Standardize null checks to use != NULL consistently
- Use break statements consistently instead of mixing return and break
- Maintain exact same functionality while improving code structure
The refactoring eliminates unnecessary nesting and makes the function's
logic flow more explicit by directly switching on the actual node type
rather than wrapping it in a redundant switch statement.
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_SCALL and NODE_FCALL node types, consolidating all method calls
into a single NODE_CALL variable-sized node structure. This simplifies the
AST by unifying call semantics while maintaining support for safe navigation
and different call types through node flags.
Key changes:
- Convert call nodes to use variable-sized allocation with call_node structure
- Unify new_call() and new_fcall() to create NODE_CALL nodes consistently
- Replace gen_call() with separate gen_call_var() and gen_call_assign_var()
- Add gen_call_assign_var() for assignment operations like h[k] = v
- Remove legacy call handling from main codegen switch statement
- Preserve argument structure using args pointer instead of unpacking
- Support safe calls, keyword arguments, and blocks in unified structure
This migration maintains backward compatibility while enabling more efficient
call node processing and reduced code duplication in the compiler.
Co-authored-by: Claude <noreply@anthropic.com>
Complete migration of method definition nodes to variable-sized format:
- Convert NODE_DEF and NODE_SDEF from fixed cons-based to variable-sized nodes
- Update parser to create variable-sized def/sdef nodes directly
- Remove old codegen_def and codegen_sdef functions
- Consolidate method setup logic in defn_setup function
- Rename lambda_body_ex to lambda_body after removing wrapper layer
- Update all method definition code generation to use new node structure
This completes the variable-sized node migration for method definitions,
improving memory efficiency and enabling more flexible AST handling.
Co-authored-by: Claude <noreply@anthropic.com>
Clean up function names by removing unnecessary _var suffixes for
consistency with other assignment functions.
Co-authored-by: Claude <noreply@anthropic.com>
created lambda_body_ex that takes locals, args, and body as separate
parameters instead of a cons structure. this eliminates complex cons
cell navigation and makes the interface cleaner for variable-sized
nodes. updated all call sites (gen_def_var, gen_sdef_var, gen_block_var,
gen_lambda_var) to use lambda_body_ex directly.
Co-authored-by: Claude <noreply@anthropic.com>
Convert NODE_LVAR and NODE_ARG from cons-list to variable-sized nodes.
Remove new_lvar wrapper and use new_xvar directly. Update parser
semantic functions and cleanup gen_assignment. Rename codegen_lvar
to gen_lvar for consistency.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_op_asgn() that created traditional
cons-list nodes when var_nodes_enabled was false. Now always creates
variable-sized nodes using struct mrb_ast_op_asgn_node.
Also remove traditional NODE_OP_ASGN codegen path and unused
codegen_op_asgn function, completing the migration to variable-sized
nodes for all operator assignment patterns.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_asgn() and inline new_asgn_var() helper
function for cleaner implementation. Assignment expressions maintain proper
value semantics while using more efficient memory allocation.
Changes:
- Remove var_nodes_enabled conditional in new_asgn()
- Inline new_asgn_var() logic directly into new_asgn()
- Remove new_asgn_var() function and declaration
- Remove NODE_ASGN case from main codegen() switch
- Update gen_asgn_var() to use direct struct field access
- Remove traditional codegen_asgn() function
Co-authored-by: Claude <noreply@anthropic.com>
Update codegen_op_asgn() to handle variable-sized nodes wrapped in NODE_VARIABLE
instead of assuming traditional cons-list format. Remove obsolete traditional
node type checks since NODE_CONST and NODE_CVAR now always use variable-sized
nodes.
The ||= operator generates special exception-handling bytecode for undefined
constant/class variable detection that requires checking the node type to
apply proper optimization.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_const() and inline new_const_var() helper
function for cleaner implementation. Update codegen to handle NODE_CONST
in both variable-sized access and assignment contexts.
Changes:
- Remove var_nodes_enabled conditional in new_const()
- Inline new_const_var() logic directly into new_const()
- Remove new_const_var() function and declaration
- Remove NODE_CONST case from main codegen() switch
- Add NODE_CONST support in gen_assignment() for variable-sized nodes
- Inline codegen_const() logic into gen_const_var()
- Remove traditional codegen_const() function
Co-authored-by: Claude <noreply@anthropic.com>
Remove var_nodes_enabled conditional from new_nvar() and traditional
NODE_NVAR case from codegen. All numbered parameter operations now use
unified variable-sized node handling.
Co-authored-by: Claude <noreply@anthropic.com>
Remove remaining NODE_GVAR/IVAR/CVAR cases from codegen switch statements
since parser now always creates variable-sized nodes. All variable operations
now use unified NODE_VARIABLE handling.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_BLOCK_ARG support from main codegen() switch and
eliminate synthetic node creation in gen_block_arg_var. The function now
handles the variable-sized node directly without creating temporary
traditional nodes on the stack.
This completes the NODE_BLOCK_ARG migration by removing the dual handling
pattern while maintaining the gen_block_arg_var function for better code
organization and readability.
Co-authored-by: Claude <noreply@anthropic.com>
remove NODE_POSTEXE from main codegen function and inline gen_postexe_var
into codegen_variable_node. remove unused codegen_postexe function since
NODE_POSTEXE is now only a marker like NODE_ARGS
Co-authored-by: Claude <noreply@anthropic.com>
migrate new_args_tail to always create variable-sized nodes and remove
legacy conditional logic from lambda_body. remove NODE_ARGS_TAIL from
codegen_variable_node since it is now only a marker like NODE_ARGS
Co-authored-by: Claude <noreply@anthropic.com>
remove conditional from new_splat to always create variable-sized nodes and
eliminate traditional NODE_SPLAT case from codegen switch. update splat marker
detection throughout codegen to handle variable-sized format and inline
codegen_splat logic into gen_splat_var.
Co-authored-by: Claude <noreply@anthropic.com>
remove codegen_negate wrapper function and inline its logic directly
into gen_negate_var. this completes NODE_NEGATE migration cleanup.
Co-authored-by: Claude <noreply@anthropic.com>
remove codegen_undef wrapper function and inline its logic directly
into gen_undef_var. this completes NODE_UNDEF migration cleanup.
Co-authored-by: Claude <noreply@anthropic.com>
remove unused node cases and their corresponding codegen functions from
traditional codegen switch. these nodes are fully migrated to variable-sized
implementation where parser only generates variable-sized nodes via
NODE_VARIABLE wrapper.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_BACK_REF case and inline codegen_back_ref logic into
gen_back_ref_var. NODE_BACK_REF now exclusively uses variable-sized nodes,
directly accessing the type field from the node structure instead of converting
through int_to_node/node_to_char.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_NTH_REF case and inline codegen_nth_ref logic into
gen_nth_ref_var. NODE_NTH_REF now exclusively uses variable-sized nodes,
directly accessing the nth value from the node structure instead of converting
through int_to_node/node_to_int.
Co-authored-by: Claude <noreply@anthropic.com>
Remove unused codegen_self function and inline its simple OP_LOADSELF logic
directly into gen_self_var. This eliminates unnecessary function call overhead
and simplifies the codebase.
Co-authored-by: Claude <noreply@anthropic.com>
Remove unused codegen_nil function and inline its simple OP_LOADNIL logic
directly into gen_nil_var. This eliminates unnecessary function call overhead
and simplifies the codebase.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_HASH and NODE_KW_HASH cases from switch statement.
Inline codegen_hash logic into gen_kw_hash_var and remove unused codegen_hash function.
Parser already creates variable-sized nodes exclusively, so all hash operations
now route through gen_hash_var() and gen_kw_hash_var() respectively.
Co-authored-by: Claude <noreply@anthropic.com>
Remove separate new_block_var function and inline its logic directly into
new_block() to follow the same pattern used for other node migrations.
Co-authored-by: Claude <noreply@anthropic.com>
Migrated both NODE_BLOCK and NODE_LAMBDA to use variable-sized nodes exclusively
while fixing compatibility issues with mixed node structures.
Parser changes:
- new_block() and new_lambda() always create variable-sized nodes
- temporarily disabled var_nodes_enabled to avoid mixed node structure issues
Codegen changes:
- removed codegen_block() and codegen_lambda() functions
- removed traditional NODE_BLOCK and NODE_LAMBDA cases from switch statement
- inlined logic into gen_block_var() and gen_lambda_var() using stack-allocated structures
- fixed lambda_body() to handle both variable-sized and cons-list NODE_ARGS_TAIL
- restored OP_KEYEND generation logic for proper keyword argument validation
All tests pass with improved memory efficiency through direct struct access.
Co-authored-by: Claude <noreply@anthropic.com>
Complete NODE_STMTS migration by removing unused codegen_stmts function
and inlining statement traversal logic directly into gen_stmts_var.
Co-authored-by: Claude <noreply@anthropic.com>
These node types always generate variable-sized nodes, so the cons-list
codegen support is no longer needed. This change:
codegen.c:
- Moves logic from codegen_break/next/redo/retry into gen_*_var functions
- Removes cons-list switch cases for these four node types
- Removes the now-unused codegen_break/next/redo/retry functions
parse.y:
- Updates call_with_block to handle NODE_BREAK and NODE_NEXT through
NODE_VARIABLE case instead of cons-list cases
- Removes the now-unused cons-list cases for these node types
All control flow functionality remains identical, but the code path is
simplified since these nodes exclusively use variable-sized structures.
Co-authored-by: Claude <noreply@anthropic.com>
Unified gen_class_var, gen_module_var, and gen_sclass_var functions by extracting
common patterns into two helper functions:
- gen_class_body() handles body generation for all three types
- gen_namespace() handles namespace/parent setup for class and module
This refactoring eliminates approximately 40 lines of duplicated code while
maintaining identical functionality and bytecode generation patterns.
Co-authored-by: Claude <noreply@anthropic.com>
- Implement complete variable-sized node generation for all class/module types
- gen_class_var(): full class definition with namespace and superclass support
- gen_module_var(): complete module definition with proper scope handling
- gen_sclass_var(): singleton class with object evaluation and OP_SCLASS
- All use scope_body() for proper locals and body management
- Update parser to always create variable-sized nodes
- Inline helper function logic directly into new_class(), new_module(), new_sclass()
- Remove conditional var_nodes_enabled checks for consistency
- Eliminate separate _var helper functions
- Remove obsolete traditional node handling
- Delete codegen_class(), codegen_module(), codegen_sclass() functions
- Remove NODE_CLASS, NODE_MODULE, NODE_SCLASS cases from main codegen() switch
- Clean up unused function declarations
- All 1730 tests pass, class/module/singleton functionality verified
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_SCOPE case from main codegen() switch and migrate all node
creation to variable-sized nodes. Add node_type_p() helper for unified
node type checking across traditional and variable-sized nodes.
Key fixes:
- Use scope_node(node->cdr) pattern for NODE_VARIABLE wrapper extraction
- Update parser_update_cxt and mrb_parser_foreach_top_variable
- Add NODE_VARIABLE support to mrb_parser_dump for bintest compatibility
- Fix mirb local variable handling preventing TypeError on evaluation
Co-authored-by: Claude <noreply@anthropic.com>
- remove conditional logic from new_rescue() and new_ensure(), always creating variable-sized nodes
- remove unused new_rescue_var() helper function
- remove traditional NODE_RESCUE and NODE_ENSURE cases from main codegen() switch
- inline codegen_rescue() logic directly into gen_rescue_var() for optimal performance
- inline codegen_ensure() logic directly into gen_ensure_var() for optimal performance
- eliminate temporary cons-like structures, using direct variable-sized node field access
- remove now-unused codegen_rescue() and codegen_ensure() functions
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_colon2() to always create variable-sized
nodes. Implement assignment support for variable-sized constant nodes with
dedicated helper functions. Remove obsolete cons list code paths from
gen_assignment() and codegen().
Co-authored-by: Claude <noreply@anthropic.com>
Following the proven NODE_HASH pattern:
- Inlined new_array_var functionality into new_array in parse.y
- Enhanced gen_array_var with full splat support from gen_values
- Removed obsolete codegen_array function and cons list NODE_ARRAY case
- All arrays now use variable-sized nodes with identical test success (1730/1731)
Co-authored-by: Claude <noreply@anthropic.com>
Modified new_hash function to always create variable-sized nodes instead of
conditionally falling back to cons list nodes. This achieves complete
NODE_HASH migration with full test suite compatibility.
Co-authored-by: Claude <noreply@anthropic.com>
Replace JMPIF+JMP pattern with JMPNOT for last condition in each when
clause, allowing when bodies to execute inline. Also eliminate no-op
JMP instructions from else clauses, reducing overall instruction count.
Co-authored-by: Claude <noreply@anthropic.com>
Replace cons-list based case statement implementation with variable-sized
nodes for improved memory efficiency. The new implementation maintains
identical register allocation behavior using the original's proven
"nil-first, align-last" strategy.
Key changes:
- Convert new_case() to create variable-sized mrb_ast_case_node directly
- Replace codegen_case() with gen_case_var() using array iteration
- Apply original register allocation logic to new node structure
- Fix else clause handling in jump dispatch logic
Supports all case statement variants:
- Bare case statements (case when condition)
- Case with values (case expr when condition)
- UPVAR combinations with closure variables
- Splat operations (*case)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove conditional logic and consolidate NODE_FOR implementation to use
variable-sized nodes exclusively. This eliminates dual code paths and
completes the NODE_FOR migration.
Changes:
- inline new_for_var into new_for, remove p->var_nodes_enabled condition
- remove new_for_var function and forward declaration
- enhance gen_for_var with complete for-loop implementation from for_body
- remove codegen_for and for_body functions
- remove NODE_FOR case from main codegen switch (traditional cons-list path)
The for-loop implementation preserves Ruby's each-based semantics with
proper block scoping, argument handling, and loop control (break/next/redo)
while providing better memory efficiency through variable-sized nodes.
Co-authored-by: Claude <noreply@anthropic.com>
Consolidate NODE_WHILE/NODE_UNTIL with MOD variants by sharing structures
and implementations, eliminating redundant code and improving maintainability.
Changes:
- remove separate mrb_ast_while_mod_node and mrb_ast_until_mod_node structures
- share mrb_ast_while_node between NODE_WHILE and NODE_WHILE_MOD variants
- share mrb_ast_until_node between NODE_UNTIL and NODE_UNTIL_MOD variants
- simplify new_while_mod to call new_while and update node_type
- simplify new_until_mod to call new_until and update node_type
- update gen_while_mod_var and gen_until_mod_var to use shared structures
The MOD variants now reuse core allocation logic from regular variants,
differing only in node_type. This eliminates code duplication while
preserving identical functionality for both pre-tested and post-tested loops.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic and consolidate NODE_IF implementation to use
variable-sized nodes exclusively. This eliminates dual code paths and
completes the NODE_IF migration started in previous commits.
Changes:
- inline new_if_var into new_if, remove p->var_nodes_enabled condition
- remove new_unless function, replace calls with new_if (swap then/else)
- remove codegen_if function, merge nil? optimization into gen_if_var
- remove NODE_IF case from main codegen switch (always wrapped in NODE_VARIABLE)
- fix nil? optimization to handle both traditional and variable-sized nodes
- update gen_if_var to use direct struct field access instead of macros
The nil? optimization now works with both node representations:
- Traditional: NODE_TYPE(condition) == NODE_CALL (preserved)
- Variable-sized: NODE_VARIABLE wrapper containing NODE_CALL struct
This ensures obj.nil? patterns generate optimized OP_JMPNIL bytecode
regardless of AST node representation.
Co-authored-by: Claude <noreply@anthropic.com>
Replace dual integer parsing paths with two-tier system:
- NODE_INT stores int32_t values directly for common case
- NODE_BIGINT stores string representation for overflow values
- Custom read_int32() function provides locale-independent parsing
- Remove unused readint() function from codegen
This eliminates confusing dual code paths while maintaining performance
for the majority of integer literals that fit in 32-bit range.
Co-authored-by: Claude <noreply@anthropic.com>
Fix mrb_bint_new_str to normalize bigint objects to regular integers
when possible. This ensures consistent object types for values that
fit in mrb_int range, fixing comparison failures in tests.
Co-authored-by: Claude <noreply@anthropic.com>
Remove obsolete cons-list node cases since control flow nodes (break,
return, next, redo, retry) and logical operators (and, or) are now
always created as variable-sized nodes. Move and/or handling to inner
switch with proper struct field access.
Co-authored-by: Claude <noreply@anthropic.com>
Remove obsolete cons-list node cases and simplify structure to direct
conditional since only NODE_VARIABLE wrapper needs to be handled after
variable-sized node migration.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional var_nodes_enabled logic from new_nil and new_self functions.
These functions now directly create variable-sized AST nodes using proper
size classes and memory allocation. Remove helper functions new_nil_var and
new_self_var as they are no longer needed.
Also update codegen to handle the new variable-sized node structure:
- Add NODE_VARIABLE handling to gen_assignment function
- Fix self-method call detection in call generation
- Update assignment generation to properly handle variable-sized nil nodes
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional var_nodes_enabled logic from new_and and new_or functions.
These functions now directly create variable-sized AST nodes using proper
size classes and memory allocation. Also remove unused codegen_and and
codegen_or functions as all code generation now goes through the variable-sized
node handlers gen_and_var and gen_or_var with proper short-circuit evaluation.
Co-authored-by: Claude <noreply@anthropic.com>