Commit Graph

366 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 62eefc21ba mruby-compiler: implement variable-sized nodes for containers and arguments
Add variable-sized node support for containers (array, hash, words, symbols)
and arguments (splat, to_ary, svalue, block_arg) to optimize memory usage
for statement blocks and argument processing.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:05 +09:00
Yukihiro "Matz" Matsumoto 47253a0fe4 mruby-compiler: implement variable-sized nodes for containers and arguments
Add variable-sized node support for containers (array, hash, words, symbols)
and arguments (splat, to_ary, svalue, block_arg) to optimize memory usage
for statement blocks and argument processing.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:05 +09:00
Yukihiro "Matz" Matsumoto da8072e00a mruby-compiler: implement variable-sized nodes for function calls and special forms
Implements variable-sized nodes for function calls and special forms
(NODE_FCALL, NODE_ZSUPER, NODE_LAMBDA) with optimized memory allocation.
These nodes now use compact variable-sized structures instead of fixed-size
headers, reducing AST memory usage.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:05 +09:00
Yukihiro "Matz" Matsumoto d01be7af0f mruby-compiler: implement variable-sized nodes for operators and expressions
Implements variable-sized nodes for operators and expressions
(NODE_NEGATE, NODE_COLON2, NODE_COLON3) with optimized memory
allocation.  These nodes now use compact variable-sized structures
instead of fixed-size headers, reducing AST memory usage.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:05 +09:00
Yukihiro "Matz" Matsumoto ada87dffdb mruby-compiler: implement variable-sized nodes for references and variables
Implements variable-sized nodes for references and variables (NODE_NTH_REF,
NODE_BACK_REF, NODE_DVAR, NODE_NVAR, NODE_MATCH) with optimized memory
allocation. These nodes now use compact variable-sized structures instead
of fixed-size headers, reducing AST memory usage.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:04 +09:00
Yukihiro "Matz" Matsumoto 761dd43b7d mruby-compiler: implement variable-sized nodes for control flows
added variable-sized nodes for control flow and string/regex variants:
- control flow: break, next, redo, retry, while_mod, until_mod
- string/regex: xstr, dxstr, dregx, heredoc, dsym
- proper integration with existing codegen patterns
- maintains backward compatibility with traditional nodes
- tested with control flow and string interpolation

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:04 +09:00
Yukihiro "Matz" Matsumoto 84c94cf18b mruby-compiler: implement variable-sized AST nodes optimization
added variable-sized node structures for memory optimization:
- simple nodes: singleton values (self, nil, true, false) and constants
- advanced nodes: complex structures (rescue, ensure, block)
- size class allocation system (TINY, SMALL, MEDIUM, LARGE, XLARGE)
- NODE_VARIABLE wrapper for flexible memory layout
- removed NODE_ARG from variable-sized implementation per analysis
- fixed memory corruption issues in gen_block_var with stack allocation
- cleaned up consecutive blank lines and unused code

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:04 +09:00
Yukihiro "Matz" Matsumoto 7836af0d52 mruby-compiler: add variable-sized simple node support
add variable-sized node structures for simple nodes (self, nil, true,
false, const) with conditional usage based on var_nodes_enabled.
singleton nodes use only 8-byte header for maximum memory efficiency.
includes proper forward declarations, casting macros, creation functions,
and codegen support maintaining compatibility with existing functions.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:04 +09:00
Yukihiro "Matz" Matsumoto c40c28c2ab mruby-compiler: add variable-sized literal node support
add variable-sized node structures for literal nodes (dstr, regx,
dot2/dot3 ranges, float) with conditional usage based on var_nodes_enabled.
includes casting macros, value access macros, creation functions,
and codegen support that maintains compatibility with existing
traditional codegen functions.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:04 +09:00
Yukihiro "Matz" Matsumoto f01cc52835 mruby-compiler: implement variable-sized AST nodes for expression operations
Add support for variable-sized AST nodes for logical and control expression
operations including AND, OR, RETURN, YIELD, and SUPER.

Changes:
- Add variable-sized node structures for expression nodes in node.h
- Add casting and value access macros for expression nodes
- Modify existing expression functions to conditionally use variable-sized versions
- Implement variable-sized node creation functions (new_and_var, new_or_var, etc.)
- Add codegen support for variable-sized expression nodes
- All expression types (AND, OR, RETURN, YIELD, SUPER) now support variable-sized allocation

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:04 +09:00
Yukihiro "Matz" Matsumoto e3d52cec12 mruby-compiler: implement variable-sized AST nodes for assignment operations
Add support for variable-sized AST nodes for assignment operations including
simple assignment, multiple assignment, and operator assignment.

Changes:
- Add variable-sized node structures for assignment nodes in node.h
- Add casting and value access macros for assignment nodes
- Modify existing assignment functions to conditionally use variable-sized versions
- Implement variable-sized node creation functions (new_asgn_var, new_masgn_var, new_op_asgn_var)
- Add codegen support for variable-sized assignment nodes
- All assignment types (simple, multiple, operator) now support variable-sized allocation

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:03 +09:00
Yukihiro "Matz" Matsumoto 21037456df mruby-compiler: implement variable-sized AST nodes for control flow constructs
Add variable-sized node structures for all control flow statements:
- IF/ELSIF/ELSE statements with optimized condition handling
- WHILE and UNTIL loops with proper jump generation
- FOR loops with iterator support
- CASE/WHEN statements with multiple condition matching

Key changes:
- Added variable-sized node structures (mrb_ast_if_node, mrb_ast_while_node,
  mrb_ast_until_node, mrb_ast_case_node, mrb_ast_for_node) to node.h
- Implemented parser functions with size class allocation in parse.y
- Added comprehensive codegen support with proper jump handling and
  stack management in codegen.c
- All control flow nodes now use NODE_VARIABLE wrapper for consistency
- Variable-sized nodes enabled by default for improved memory efficiency

This provides memory-efficient storage for control flow constructs while
maintaining full compatibility with existing functionality.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:03 +09:00
Yukihiro "Matz" Matsumoto b534621957 mruby-compiler: implement variable-sized ast nodes for control flow
This completes the implementation of variable-sized AST nodes for control flow
structures (if, while, for, case), further reducing memory usage. Changes were
verified with AddressSanitizer.

Co-authored-by: Gemini <gemini@google.com>
2025-10-03 19:46:03 +09:00
Yukihiro "Matz" Matsumoto 392f4fabc0 mruby-compiler: use variable-sized ast nodes for call, array, and hash
Introduces variable-sized AST nodes for method calls (NODE_CALL),
arrays (NODE_ARRAY), and hashes (NODE_HASH). This change improves
memory efficiency by storing elements directly within the AST node,
avoiding an extra layer of pointer indirection for their data.

This is achieved by adding new data structures and functions in both
the parser and the code generator to handle these new node types.
Variable-sized nodes are now enabled by default.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:03 +09:00
Yukihiro "Matz" Matsumoto ac02635ba5 mruby-compiler: add infrastructure for variable-sized ast nodes
This commit introduces the core infrastructure for variable-sized AST
nodes, designed to improve memory efficiency. The previous fixed-size
nodes are replaced by nodes that can store data inline, such as
strings and integers, reducing pointer indirection and memory overhead.

Key changes include:
- A generic variable-sized node header (`mrb_ast_var_header`).
- A size-class-based memory allocation system for these nodes.
- Implementation of variable-sized nodes for core types: symbols,
  strings, integers, and variables (lvar, gvar, ivar, cvar).
- Integration into the parser and code generator, controlled by a
  feature flag.
- Centralized and improved type-casting macros for AST nodes.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:03 +09:00
Yukihiro "Matz" Matsumoto 8c36e227e7 mruby-compiler: implement head-only location optimization for ast nodes
This implements a memory optimization for AST nodes that stores location
information (lineno, filename_index) only in head nodes rather than in
every node, reducing memory usage for structure nodes.

Key changes:
- Split node types: mrb_ast_node (structure nodes without location),
  mrb_ast_head_node (with location info). Sizes are platform-dependent:
  8/12 bytes on 32-bit, 16/24 bytes on 64-bit platforms
- Separate allocation: cons() creates structure nodes, cons_head()
  creates head nodes with location information
- Node recycling: all nodes are recycled when freed, but only smaller
  structure nodes are reused from the free list to maintain type safety
- Updated macro: added headn() for consistent head node casting
- Removed NODE_LINENO macro: eliminated redundant location copying
  since head-only optimization already provides adequate location info
- Fixed codegen to properly access location fields via head node casts

This optimization reduces AST memory usage while preserving all
debugging and location information functionality.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-03 19:46:03 +09:00
Yukihiro "Matz" Matsumoto ee30d1d0f8 mruby-compiler: allow at-least-once loop behavior for mruby
mruby does not provide `begin ... end while cond` that behave at-least-once
loop, like CRuby does. It remains in TODO.md for long time. But finally we have
implemented the behavior.
2025-07-11 10:09:34 +09:00
Yukihiro "Matz" Matsumoto ebc10f3c57 Add NODE_BEGIN for explicit begin...end blocks
This commit introduces NODE_BEGIN as a distinct AST node type for
explicit begin...end blocks, separate from NODE_STMTS which represents
general statement sequences. This distinction will be essential for
implementing CRuby-compatible begin...end while/until constructs.

Key changes:
- Added NODE_BEGIN enum in node.h
- Added new_begin() function in parse.y using optimized cons() structure
- Modified begin...end grammar rule to generate NODE_BEGIN nodes
- Added NODE_BEGIN codegen support in codegen.c
- Added NODE_BEGIN to parser dump functionality

NODE_BEGIN uses a simpler cons() structure instead of list2() for
better memory efficiency, as it only contains a single body node.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-11 10:09:34 +09:00
Yukihiro "Matz" Matsumoto dc0a5f433f mruby-compiler: optimize NODE_STMTS nesting to reduce AST depth
Modify new_stmts to flatten unnecessary nesting by returning existing
NODE_STMTS directly instead of wrapping them. This reduces memory usage
and AST complexity when multiple parentheses levels are used.

Before: (((expr1; expr2))) creates nested NODE_STMTS
After: (((expr1; expr2))) creates single NODE_STMTS with statements

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-11 10:09:33 +09:00
Yukihiro "Matz" Matsumoto f6c166cbb0 mruby-compiler: rename NODE_BEGIN to NODE_STMTS for clarity
Rename NODE_BEGIN to NODE_STMTS to better reflect its purpose as a
container for statement sequences, not specifically begin-end blocks.
This prepares for adding a dedicated node type for explicit begin-end
constructs.

- Rename NODE_BEGIN enum to NODE_STMTS in node.h
- Update all references in parse.y and codegen.c
- Rename new_begin function to new_stmts

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-11 10:09:33 +09:00
Yukihiro "Matz" Matsumoto bb712f9467 mruby-compiler: remove mrb_calloc dependency from parse.y 2025-05-19 08:00:36 +09:00
Yukihiro "Matz" Matsumoto 9fc58852e3 mruby-compiler: removed mrb_state dependency from two functions
- mrb_ccontext_partial_hook
- mrb_ccontext_cleanup_local_variables
2025-05-19 08:00:36 +09:00
Yukihiro "Matz" Matsumoto 75466f9aab mruby-compiler: use mrb_basic_alloc_func() directly from compiler
As a side effect, memory allocation failure may cause segmentation
fault. Maybe we have to add error detection later.
2025-05-13 13:20:06 +09:00
Yukihiro "Matz" Matsumoto 9ef2f551b7 mruby-compiler: use new mempool API 2025-05-13 08:13:48 +09:00
John Bampton b1d910f6f4 mrbgems: fix spelling 2025-04-04 15:05:13 +10:00
Yukihiro "Matz" Matsumoto eb455c19fe mruby-compiler: prohibit singleton methods for literals
We have checked `def (literal).m` style but not `def literal.m` style.
In addition, `NODE_INT` check is newly added.
2025-03-14 23:28:42 +09:00
Yukihiro "Matz" Matsumoto 111fe4b3be mruby-compiler: generate OP_SSEND from Complex and Rational literals 2025-03-07 17:17:45 +09:00
Hoshiumi Arata 386cd771e7 Fix numbered parameters when used as hash keys 2024-11-20 00:31:44 +09:00
Yukihiro "Matz" Matsumoto 628f057482 Merge pull request #6419 from hoshiumiarata/fix_numparams_in_lambda 2024-11-15 16:17:03 +09:00
Hoshiumi Arata 9fe2a5c46a parser: setup numbered parameters in new_lambda and adjust dump_prefix offset 2024-11-13 22:19:27 +09:00
Hoshiumi Arata cc2ec53807 parser: support numbered parameters when used as a singleton 2024-11-13 00:22:49 +09:00
dearblue ff9c03fde4 Put #include <stdlib.h> in parse.y
ref. #6388
2024-11-06 22:29:29 +09:00
Yukihiro "Matz" Matsumoto 49525fa207 mempool.c: renamed from pool.c
To avoid confusion with pools in irep, we renamed region-based memory
manager from pool to mempool.

- rename pool.c to mempool.c
- separate mempool.h
- rename all mrb_pool to mrb_mempool

So if someone is using pool.c functions (I suppose no one does though),
they need to rename all `mrb_pool` to `mrb_mempool` and include
`mruby/mempool.h` header at the top.
2024-10-31 14:06:10 +09:00
Yukihiro "Matz" Matsumoto b95ca53e5c mruby-compiler: revert ce2fdb7; close #6388
The commit was to stop warnings from Visual C but unexpectedly caused
compilation errors on some configuration.
2024-10-22 14:46:12 +09:00
Yukihiro "Matz" Matsumoto 51fd065722 mruby-compiler (parser_yylex): skip sign if bigint starts with +
To reserve memory (1 byte) and avoid error (fixed by 11cff8f).
2024-10-22 14:45:48 +09:00
Yukihiro "Matz" Matsumoto e29f3d64b2 mruby-compiler: stop malloc/free warnings from Visual Studio build 2024-10-11 09:10:44 +09:00
Yukihiro "Matz" Matsumoto 9c5812a463 mruby-compier: keep stack reference to passed block after modifying &b
To mark `MRB_PROC_ORPHAN` we need to keep track of passed block, even
after the assignment to the block argument. And `yield` should use the
original block; #5786, #5791, #6369
2024-09-26 02:48:16 +09:00
leviongit 87801ed5f1 codegen.c,parse.y: remove flattening of yield arguments; fix #6346
this commit changes the parse tree of the `yield` node, allowing for
proper keyword argument generation
2024-09-09 10:06:31 +02:00
Yukihiro "Matz" Matsumoto 56a82009aa Revert "The lex_state after literals should be EXPR_ENDARG."; fix #6298
This reverts commit e98823f189.
2024-08-10 19:17:49 +09:00
Yukihiro "Matz" Matsumoto d6da2d4760 mruby-compiler: use @1 in parse.y to enable YYLTYPE
This change itself does nothing good, but it is a preparation for the
future Bison to Lrama migration. As of 0.6.9, Lrama has a compatibility
issue for grammar files without `@n`.
2024-06-10 08:23:36 +09:00
Yukihiro "Matz" Matsumoto 889af10090 mruby-compiler: prohibit dynamic assignment to constants; #3521
Along with some declaration adjustments to minimize `y.tab.c` diff.
2024-06-05 18:56:11 +09:00
Yukihiro "Matz" Matsumoto 6de4df3b31 parse.y: replace mrbc_ prefix by mrb_ccontext 2023-12-06 15:32:13 +09:00
Yukihiro "Matz" Matsumoto d7b2e3ab14 mruby-compiler/parse.y: add print name for identifier tokens 2023-09-05 23:29:24 +09:00
Yukihiro "Matz" Matsumoto 2f7f797473 remove extra spaces before ; 2023-05-22 12:05:35 +09:00
Yukihiro "Matz" Matsumoto c32f7915fb reformat else clause indentation style 2023-05-20 00:21:01 +09:00
Yukihiro "Matz" Matsumoto bdbc613ccb parse.y (mrbc_filename): should not raise exceptions 2023-03-22 17:33:49 +09:00
Yukihiro "Matz" Matsumoto 7f79ca2cf6 mruby-compiler: need to adjust the line number for do_block; fix #5949 2023-03-11 15:49:35 +09:00
Yukihiro "Matz" Matsumoto 55eea005c8 mruby/internal.h: add codedump functions to the internal function header
ref #5906
2023-01-18 10:37:48 +09:00
dearblue c101261f45 Call mrb_env_unshare() in mrb_top_run() if necessary
This is to keep the local variables of the previously created blocks consistent in case the `mrbc_context` passed to `mrb_load_exec()` is `NULL` or different.
Switching between `mrbc_context` pointers that are non `NULL` can be done safely by calling `mrbc_cleanup_local_variables()`.

Before this patch, the result of the following code is not as expected.

```console
% cat loadstr.c
#include <mruby.h>
#include <mruby/compile.h>

int
main(int argc, char *argv[])
{
  mrb_state *mrb = mrb_open();

  mrb_load_string(
      mrb,
      "(a, b, c, d, e, f, g) = [1, 2, 3, 4, 5, 6, 7] \n"
      "$lambda = -> { p [a, b, c, d, e, f, g] }");
  mrb_load_string(mrb, "$lambda.call");

  mrb_close(mrb);

  return 0;
}

% $(bin/mruby-config --cc --cflags --ldflags) loadstr.c $(bin/mruby-config --libs) && ./a.out
[main, nil, nil, main, nil, nil, main]
```

Also, since `mrb_env_unshare()` was not used before, the internal stack of simply detached `env` objects could show invalid addresses by `stack_extend()`.
ref. https://github.com/kou/mruby-pp/commit/ef5951aca870183d8767cb61f6414240988ca35e
2023-01-09 22:47:37 +09:00
Yukihiro "Matz" Matsumoto f7a8a42521 mruby-compiler/parse.y: allow multiple anonymous splat in args rule
For example, this should be allowed:

```ruby
def f(*)
  p(*,*)
end
```
2022-12-17 09:37:44 +09:00