pr #6643 fixed node type check but introduced a bug by accessing t->cdr
on a NODE_ARRAY structure. NODE_ARRAY nodes use the elements field, not
cdr. additionally, the fixed rhs path needs to update rhs_reg to point
to where values are actually pushed on the stack.
Co-authored-by: Claude <noreply@anthropic.com>
segment nodes allocated with mrbc_malloc were leaked if gen_string
raised an exception via longjmp. fix by avoiding allocation entirely:
temporarily modify tree structure by saving and clearing cdr pointer,
call gen_string, then restore cdr. no memory is allocated so nothing
leaks even on longjmp.
Co-authored-by: Claude <noreply@anthropic.com>
The bug was in codegen_colon3 which used genop_2(OP_OCLASS, sym)
treating OCLASS as BB format, but OCLASS is B format that only
loads ::Object without a symbol parameter. The fix uses the correct
two-instruction pattern: OCLASS to load Object class, then GETMCNST
to retrieve the constant from it.
Co-authored-by: Claude <noreply@anthropic.com>
cast uint8_t node_type field to enum node_type to satisfy c++ stricter
type checking while maintaining memory efficiency of 1-byte storage.
Co-authored-by: Claude <noreply@anthropic.com>
Remove migration-stage "Phase" and "Group" references from comments,
replacing them with descriptions of actual code organization.
Co-authored-by: Claude <noreply@anthropic.com>
replaced all *_NODE_* accessor macros (e.g., SYM_NODE_VALUE,
INT_NODE_VALUE, CALL_NODE_METHOD) with direct member access using
casting macros (e.g., sym_node(n)->symbol, int_node(n)->value,
call_node(n)->method_name). this eliminates an unnecessary abstraction
layer and improves code readability by making field access explicit.
the accessor macros simply wrapped cast_func(n)->field, providing no
real benefit. direct member access makes it clear what field is being
accessed and reduces macro indirection.
affected files:
- node.h: removed ~100 accessor macro definitions
- codegen.c: replaced 19 macro uses with direct access
- parse.y: replaced 152 macro uses with direct access
Co-authored-by: Claude <noreply@anthropic.com>
replaced unnecessary macro usage with direct struct member access when
struct pointers are already available:
- return_n->args instead of RETURN_NODE_ARGS(return_n)
- yield_n->args instead of YIELD_NODE_ARGS(yield_n)
- for_n->var/iterable/body instead of FOR_NODE_VAR/ITERABLE/BODY(for_n)
- class_n->name/superclass/body instead of CLASS_NODE_* macros
- module_n->name/body instead of MODULE_NODE_NAME/BODY(module_n)
- sclass_n->obj/body instead of SCLASS_NODE_OBJ/BODY(sclass_n)
- hash->pairs instead of HASH_NODE_PAIRS(hash)
- call->method_name/safe_call instead of CALL_NODE_METHOD/SAFE(call)
- array->elements and an->elements instead of ARRAY_NODE_ELEMENTS macro
- splat->value instead of SPLAT_NODE_VALUE macro
improves code readability by removing unnecessary indirection.
Co-authored-by: Claude <noreply@anthropic.com>
Refactored NODE_DSYM to use unified structure directly instead of wrapping
NODE_STR. This eliminates unnecessary allocation and simplifies the AST.
Changes:
- new_dsym() now creates NODE_DSYM directly with mrb_ast_str_node structure
- Parser calls new_dsym(p, n) instead of new_dsym(p, new_str(p, n))
- codegen_dsym() uses gen_string() for proper string generation
- NODE_DSYM dump uses dump_str() for consistent string list handling
- Removed redundant mrb_ast_dsym_node struct definition
This maintains identical functionality while reducing memory overhead
and architectural complexity, with proper string handling to prevent
mrbtest crashes.
Co-authored-by: Claude <noreply@anthropic.com>
Implement NODE_MARG as a dedicated node type for parameter destructuring
to separate it architecturally from general multiple assignment (NODE_MASGN).
This resolves crashes when dumping parameter destructuring nodes and
improves code organization.
Key changes:
- Add NODE_MARG to node type enum
- Create new_marg() function for parameter destructuring
- Consolidate new_masgn() and new_marg() using shared helper
- Fix parameter context checks in lambda_body() to use NODE_MARG only
- Enable shared dumping logic for both NODE_MASGN and NODE_MARG
- Optimize memory management with immediate RHS cleanup
- Combine gen_assignment() cases for code deduplication
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Refactored NODE_MASGN from single lhs field to separate pre/rest/post
fields for cleaner multiple assignment handling. Fixed segfault when
compiling methods with destructured parameters by properly handling
parameter destructuring in lambda_body function.
Co-authored-by: Claude <noreply@anthropic.com>
- Skip no-op splats of empty array literals (`*[]` / zarray) in
call argument generation and array literal codegen.
- Inline non-empty literal splat arrays without inner splats
(e.g. `*[a,b]`) as regular positional args/elements, avoiding
building a temporary array and ARYCAT.
This removes unnecessary `LOADNIL` + `ARRAY 0` + `ARYCAT` sequences
(e.g. `mruby -ve 'p *[]'`) and reduces temporary allocations while
preserving semantics and evaluation order. Falls back to the generic
path when nested splats are present or counts exceed fixed-arity.
No behavior change intended; only codegen improvements.
Co-authored-by: Codex <codex@openai.com>
Now that all cons-list based codegen_* functions have been removed,
rename the gen_*_var functions to use the consistent codegen_* prefix.
This affects 70 functions and improves code clarity by establishing
a single naming convention for all code generation functions.
- gen_scope_var renamed to codegen_scope_node to avoid conflict with codegen_scope type
- All other gen_*_var functions renamed to codegen_* (removing _var suffix)
- Updated all function calls throughout codegen.c
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_MATCH enum value, structure definition, accessor macro,
parser dump case, codegen case, and gen_match_var function. This
node type was never actually used in the parser.
Co-authored-by: Claude <noreply@anthropic.com>
Remove the original NODE_REGX node type and related infrastructure,
then rename NODE_DREGX to NODE_REGX to consolidate regex handling
under a single node type.
Changes based on git diff:
- Remove original mrb_ast_regx_node structure with pattern fields
- Remove gen_regx_var() function handling literal regex patterns
- Remove NODE_REGX case from codegen and parser dump
- Rename NODE_DREGX to NODE_REGX for dynamic regex expressions
- Update all related functions and structure references
Co-authored-by: Claude <noreply@anthropic.com>
Remove the last cons list dependency in codegen.c by inlining codegen_regx()
directly into gen_regx_var(). This eliminates the need to create temporary
cons list structures and directly accesses regex pattern, flags, and
encoding from the variable-sized node structure.
Changes:
- Inline codegen_regx() logic into gen_regx_var()
- Remove codegen_regx() function entirely
- Access regex data directly from mrb_ast_regx_node fields
- Eliminate temporary cons list node creation
Co-authored-by: Claude <noreply@anthropic.com>
Remove argc, has_kwargs, has_block, and reserved fields from
mrb_ast_call_node since this information can be determined from the
callargs structure at runtime. Simplify new_call() and call_with_block()
functions to eliminate field analysis during parsing.
Add callargs_empty() helper function to check for empty arguments and
update gen_if_var() to use it instead of accessing removed argc field.
This change reduces memory usage per call node while maintaining full
functionality through runtime analysis of the callargs structure.
Co-authored-by: Claude <noreply@anthropic.com>
Eliminate code duplication in gen_string by using a single loop with
a first-element flag instead of separate first element processing.
The previous structure had ~20 lines of duplicated string literal and
expression processing logic. The refactored version uses a unified loop
that handles concatenation only for non-first elements, reducing code
duplication and improving maintainability.
Functionality remains identical - all string interpolation, regex
patterns, and heredoc processing work correctly.
Co-authored-by: Claude <noreply@anthropic.com>
Rename the overly long and poorly descriptive codegen_cons_list_string()
function to gen_string() which is more concise and follows the existing
naming convention where gen_ prefix indicates code generation functions.
This function generates string bytecode from cons-list structures
containing mixed string literals and expressions for interpolation,
used in string interpolation, regex patterns, and heredocs.
Co-authored-by: Claude <noreply@anthropic.com>
Modernize the parser dump functionality to support the post-NODE_VARIABLE
hybrid AST architecture with both variable-sized nodes and traditional
cons-list nodes.
Co-authored-by: Claude <noreply@anthropic.com>
This removes the NODE_VARIABLE enum and associated wrapper system, updating
the parser and codegen to work directly with variable-sized AST nodes.
Key changes:
- Removed NODE_VARIABLE from node.h enum
- Updated parser functions to handle direct variable-sized nodes
- Fixed codegen() main dispatch to detect variable-sized nodes directly
- Added helper functions for node type detection and header access
- Updated all parser and codegen functions to work with modern AST structure
Co-authored-by: Claude <noreply@anthropic.com>
Updates codegen() function to retrieve filename and line number information
directly from variable-sized node headers instead of assuming traditional
head nodes. Removes dead code for traditional cons-list nodes since all
nodes are now variable-sized.
Co-authored-by: Claude <noreply@anthropic.com>
Eliminates NODE_KW_HASH enum, mrb_ast_kw_hash_node struct, gen_kw_hash_var
function, and related macros. All keyword hash functionality now unified
under NODE_HASH, completing the AST simplification.
Co-authored-by: Claude <noreply@anthropic.com>
Removes the new_kw_hash function entirely and replaces all calls with
new_hash, eliminating the distinction between keyword hashes and regular
hashes in the parser. Updates codegen to handle keyword arguments directly
without intermediate cdr references.
Co-authored-by: Claude <noreply@anthropic.com>
Following the same pattern as the case node upgrade (e0f07c9), this
change eliminates the complex flat array packing approach for hash nodes
in favor of simple cons-list storage. The flat array packing provided
no memory benefit since cons lists aren't recycled, while adding
unnecessary complexity to both allocation and traversal logic.
Changes:
- Simplified mrb_ast_hash_node structure from variable-sized flexible
array to fixed-size structure with cons-list pointer
- Reduced new_hash() from complex 30+ line allocation to simple 4-line
pattern matching array node implementation
- Updated gen_hash_var() to use cons-list iteration instead of
interleaved array access (pairs[i*2] for key, pairs[i*2+1] for value)
- Removed HASH_NODE_LEN macro as length tracking is no longer needed
- Maintains identical functionality while reducing code complexity
Co-authored-by: Claude <noreply@anthropic.com>
Replace complex flat array packing with simple cons-list storage to reduce
memory overhead and code complexity. This continues the compiler simplification
work by reverting array nodes to the original memory-efficient approach.
- Remove len/flags fields from mrb_ast_array_node structure
- Eliminate complex two-pass processing (count + copy) in new_array()
- Replace array indexing with cons-list iteration in gen_array_var()
- Reduce parser code from 30+ lines to 4 lines for array creation
- Maintain full functionality with zero test regressions
Following the same successful pattern used for mrb_ast_case_node upgrade,
this change proves that flat array packing provides no memory benefit
since cons lists aren't recycled, while adding unnecessary complexity.
Co-authored-by: Claude <noreply@anthropic.com>
Replace NODE_KW_REST_ARGS wrapper nodes with direct ** symbol markers to
reduce memory overhead and simplify code structure. This continues the
compiler simplification work by unifying keyword rest arguments with
other node types while maintaining full functionality.
Co-authored-by: Claude <noreply@anthropic.com>
Replace NODE_KW_ARG wrapper with direct (key . value) cons structure,
eliminating unnecessary memory overhead and access indirection.
Changes:
- Remove NODE_KW_ARG node type from enum
- Modify new_kw_arg() to return direct cons instead of wrapped structure
- Update codegen.c to use simplified access patterns (k->car->car, k->car->cdr)
- Fix new_args_tail() to handle simplified keyword argument structure
- Remove NODE_KW_ARG case from parser dump function
This reduces memory usage from 3 cons cells to 1 per keyword argument
while maintaining full functionality and following mruby's design priority
of memory efficiency over complexity.
Co-authored-by: Claude <noreply@anthropic.com>
Replace variable-sized NODE_VARIABLE wrapper with fixed-size struct
allocation, following the same pattern as new_args(). This eliminates
the need for NODE_VARIABLE checking and uses direct casting instead.
Changes:
- Remove mrb_ast_var_header from callargs struct
- Use parser_palloc instead of parser_alloc_var for fixed-size allocation
- Update all access points to use direct casting: (struct mrb_ast_callargs*)
- Remove unnecessary backward compatibility code for newly introduced NODE_CALLARGS
Co-authored-by: Claude <noreply@anthropic.com>
Rename mrb_ast_op_asgn_node.operator field to op to avoid conflict with
C++ operator keyword. Update all references including macro definitions
and field access code.
Co-authored-by: Claude <noreply@anthropic.com>
- Remove obsolete NODE_ARGS_TAIL enum value and all references
- Simplify mrb_ast_case_node from variable-sized array back to simple cons-list structure
- Update new_case() function to use original cons-list approach instead of flattening
- Fix infinite loop in gen_case_var() when case statements have no matching clauses
- Improve code readability by renaming pos3 to case_end_jumps in gen_case_var()
- Restore memory-efficient case statement parsing without complex array management
The variable-sized array approach for case nodes provided no memory benefit
since cons lists aren't recycled. This change restores the simpler original
implementation while fixing a critical bug that caused mrbtest to hang
on "register window of calls" test.
Co-authored-by: Claude <noreply@anthropic.com>
NODE_ARG and NODE_LVAR were handled identically in codegen.c, making
the distinction unnecessary. This change:
- Replaces all new_arg() calls with new_xvar(p, sym, NODE_LVAR)
- Removes the new_arg() function entirely
- Removes the unused NODE_ARG enum value
- Updates codegen.c to handle only NODE_LVAR case
The simplification reduces parser complexity while maintaining identical
functionality for argument processing.
Co-authored-by: Claude <noreply@anthropic.com>
This commit completes the transformation of mruby's argument processing from
cons-list based representation to direct struct field access.
Key changes:
- Transform new_args() to return struct mrb_ast_args* instead of cons-list
- Update lambda_body() to use direct struct field access for all argument types
- Fix anonymous keyword rest (**) to use intern_op(pow) marker for proper bytecode generation
- Fix argument forwarding (...) to correctly pass rest_arg to new_args()
- Eliminate mrb_ast_args_tail_node allocation by embedding fields directly in mrb_ast_args
- Update all node structure definitions to use struct mrb_ast_args*
- Remove unused NODE_ARGS enum value since args are now plain C structs
The new approach provides:
- More efficient memory usage by eliminating intermediate cons-list allocations
- Cleaner code generation with direct struct field access
- Proper distinction between anonymous kwrest and no kwrest
- Correct bytecode generation for both anonymous kwrest and argument forwarding
Fixes both anonymous keyword rest (def m(**) end) and argument forwarding
(def a(...) p(...) end) to generate correct bytecode and execute properly.
Co-authored-by: Claude <noreply@anthropic.com>
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 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>