diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2be0fbd92..619235e9f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,11 +5,27 @@ updates: directory: "/" schedule: interval: "daily" + groups: + bundler-dependencies: + patterns: + - "*" cooldown: default-days: 7 - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" + groups: + github-actions-dependencies: + patterns: + - "*" cooldown: default-days: 7 + - package-ecosystem: "pre-commit" + directory: "/" + schedule: + interval: "daily" + groups: + pre-commit-hooks: + patterns: + - "*" diff --git a/.github/linters/mlc_config.json b/.github/linters/mlc_config.json deleted file mode 100644 index 25acbbb12..000000000 --- a/.github/linters/mlc_config.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "retryOn429": true, - "retryCount": 3, - "aliveStatusCodes": [ - 200, - 206, - 502 - ], - "ignorePatterns": [ - { - "pattern": "^https://github.com/mruby/mruby/commit/" - }, - { - "pattern": "^http://jp.rubyist.net/magazine/\\?0034-Enumerable_lz" - }, - { - "pattern": "^https://ruby-doc.org/core-2.3.3" - }, - { - "pattern": "^mailto:" - }, - { - "pattern": "^https://www.iso.org/" - } - ] -} diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 00ddfa2c2..8848e68cc 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -34,7 +34,7 @@ jobs: echo \`\`\` } > "$GITHUB_STEP_SUMMARY" - name: Upload coverage report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: coverage-${{ github.sha }} path: coverage/ diff --git a/.github/workflows/oss-fuzz.yml b/.github/workflows/oss-fuzz.yml index c912a3798..6a8ded6ae 100644 --- a/.github/workflows/oss-fuzz.yml +++ b/.github/workflows/oss-fuzz.yml @@ -20,7 +20,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: artifacts diff --git a/.github/workflows/pre-commit-manual.yml b/.github/workflows/pre-commit-manual.yml new file mode 100644 index 000000000..d984b2235 --- /dev/null +++ b/.github/workflows/pre-commit-manual.yml @@ -0,0 +1,20 @@ +# https://github.com/j178/prek +name: Manual hooks + +on: [pull_request] + +permissions: + contents: read + +jobs: + pre-commit: + name: Run pre-commit + runs-on: ubuntu-latest + steps: + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v6 + - uses: j178/prek-action@v1 + with: + install-only: true + - name: Run manual pre-commit hooks + run: prek run --color=always --all-files --hook-stage manual diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 6a12bf405..63e3a7e90 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -16,5 +16,3 @@ jobs: - uses: j178/prek-action@v1 with: extra-args: --all-files - - name: Run manual pre-commit hooks - run: prek run --color=always --all-files --hook-stage manual diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 37b656628..afbeaf532 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,10 +20,11 @@ repos: - id: prettier name: run prettier description: format files with prettier - entry: prettier --write '**/*.json' '**/*.md' '**/*.yaml' '**/*.yml' - files: \.(json|md|ya?ml)$ + entry: prettier --write '**/*.md' '**/*.yaml' '**/*.yml' + files: \.(md|ya?ml)$ language: node additional_dependencies: ["prettier@3.7.4"] + pass_filenames: false stages: [manual] - id: check-zip-file-is-not-committed name: disallow zip files @@ -55,9 +56,6 @@ repos: - id: check-executables-have-shebangs exclude: ^test/t/lang\.rb$ - id: check-illegal-windows-names - - id: pretty-format-json - args: [--autofix, --no-sort-keys] - - id: check-json - id: check-merge-conflict - id: check-shebang-scripts-are-executable - id: check-vcs-permalinks @@ -107,16 +105,6 @@ repos: args: [--config=.github/linters/.markdown-lint.yml] types: [markdown] files: \.md$ - - repo: https://github.com/tcort/markdown-link-check - rev: v3.14.2 - hooks: - - id: markdown-link-check - name: run markdown-link-check - description: checks hyperlinks in Markdown files - args: [--config=.github/linters/mlc_config.json, -q] - stages: [manual] - types: [markdown] - files: \.md$ - repo: https://github.com/rubocop/rubocop rev: v1.81.7 hooks: diff --git a/.prettierignore b/.prettierignore index 0728a7c3a..8ed001b58 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,3 +3,4 @@ build coverage doc/internal/opcode.md tools/lrama +.venv diff --git a/doc/README.md b/doc/README.md index 13febf02b..0d6f6e617 100644 --- a/doc/README.md +++ b/doc/README.md @@ -4,44 +4,44 @@ New to mruby? Start here: -| Document | Description | -| -------- | ----------- | +| Document | Description | +| -------------------------------------------- | -------------------------------------- | | [Getting Started](guides/getting-started.md) | Build mruby and run your first program | -| [Language Features](guides/language.md) | Ruby subset supported by mruby | -| [Limitations](limitations.md) | Behavioral differences from CRuby | +| [Language Features](guides/language.md) | Ruby subset supported by mruby | +| [Limitations](limitations.md) | Behavioral differences from CRuby | ## Guides (for embedders and gem authors) ### Embedding mruby in C -| Document | Description | -| -------- | ----------- | -| [C API Reference](guides/capi.md) | Values, classes, methods, error handling, fibers | -| [GC Arena](guides/gc-arena-howto.md) | Managing temporary objects in C extensions | -| [Linking](guides/link.md) | Linking with `libmruby` | -| [Amalgamation](guides/amalgamation.md) | Single-file build for easy integration | -| [Precompiled Symbols](guides/symbol.md) | Compile-time symbol allocation | +| Document | Description | +| --------------------------------------- | ------------------------------------------------ | +| [C API Reference](guides/capi.md) | Values, classes, methods, error handling, fibers | +| [GC Arena](guides/gc-arena-howto.md) | Managing temporary objects in C extensions | +| [Linking](guides/link.md) | Linking with `libmruby` | +| [Amalgamation](guides/amalgamation.md) | Single-file build for easy integration | +| [Precompiled Symbols](guides/symbol.md) | Compile-time symbol allocation | ### Building and Configuring -| Document | Description | -| -------- | ----------- | -| [Compilation](guides/compile.md) | Build system, cross-compilation, toolchains | -| [Build Configuration](guides/mrbconf.md) | Compile-time macros (`MRB_*` flags) | -| [mrbgems](guides/mrbgems.md) | Creating and managing gems | -| [Memory](guides/memory.md) | Allocator customization and heap regions | +| Document | Description | +| ---------------------------------------- | ------------------------------------------- | +| [Compilation](guides/compile.md) | Build system, cross-compilation, toolchains | +| [Build Configuration](guides/mrbconf.md) | Compile-time macros (`MRB_*` flags) | +| [mrbgems](guides/mrbgems.md) | Creating and managing gems | +| [Memory](guides/memory.md) | Allocator customization and heap regions | ### Tools -| Document | Description | -| -------- | ----------- | -| [Debugger](guides/debugger.md) | Using `mrdb` for debugging | +| Document | Description | +| ----------------------------------------------- | ----------------------------------------------- | +| [Debugger](guides/debugger.md) | Using `mrdb` for debugging | | [ROM Method Tables](guides/rom-method-table.md) | Read-only method tables for constrained devices | ### Reference -| Document | Description | -| -------- | ----------- | +| Document | Description | +| ------------------------------------- | ------------------ | | [Directory Structure](guides/hier.md) | Source tree layout | ## Internals (for mruby contributors) @@ -49,14 +49,14 @@ New to mruby? Start here: Start with [Architecture](internal/architecture.md) for an overview, then dive into the subsystem you need: -| Document | Description | -| -------- | ----------- | -| [Architecture](internal/architecture.md) | Overview of object model, VM, GC, compiler | -| [Virtual Machine](internal/vm.md) | Dispatch loop, call frames, method lookup, fibers | -| [Garbage Collector](internal/gc.md) | Tri-color marking, write barriers, generational GC | -| [Compiler Pipeline](internal/compiler.md) | Parser, code generator, IRep, binary format | -| [Opcodes](internal/opcode.md) | VM instruction set reference | -| [Value Boxing](internal/boxing.md) | How `mrb_value` encodes types | +| Document | Description | +| ----------------------------------------- | -------------------------------------------------- | +| [Architecture](internal/architecture.md) | Overview of object model, VM, GC, compiler | +| [Virtual Machine](internal/vm.md) | Dispatch loop, call frames, method lookup, fibers | +| [Garbage Collector](internal/gc.md) | Tri-color marking, write barriers, generational GC | +| [Compiler Pipeline](internal/compiler.md) | Parser, code generator, IRep, binary format | +| [Opcodes](internal/opcode.md) | VM instruction set reference | +| [Value Boxing](internal/boxing.md) | How `mrb_value` encodes types | ## Release Notes diff --git a/doc/guides/capi.md b/doc/guides/capi.md index d6a94c3d4..f5c24152e 100644 --- a/doc/guides/capi.md +++ b/doc/guides/capi.md @@ -99,23 +99,23 @@ mrb_str_to_cstr(mrb, v) /* const char* from String value */ ### Value Types -| `mrb_vtype` | Ruby Class | Notes | -| ----------- | ---------- | ----- | -| `MRB_TT_FALSE` | FalseClass/NilClass | `nil` has `MRB_TT_FALSE` | -| `MRB_TT_TRUE` | TrueClass | | -| `MRB_TT_INTEGER` | Integer | Immediate value | -| `MRB_TT_FLOAT` | Float | May be immediate | -| `MRB_TT_SYMBOL` | Symbol | Immediate value | -| `MRB_TT_STRING` | String | Heap object | -| `MRB_TT_ARRAY` | Array | Heap object | -| `MRB_TT_HASH` | Hash | Heap object | -| `MRB_TT_OBJECT` | Object | User-defined classes | -| `MRB_TT_CLASS` | Class | | -| `MRB_TT_MODULE` | Module | | -| `MRB_TT_PROC` | Proc | | -| `MRB_TT_CDATA` | (C data) | Wrapped C structs | -| `MRB_TT_EXCEPTION` | Exception | | -| `MRB_TT_FIBER` | Fiber | | +| `mrb_vtype` | Ruby Class | Notes | +| ------------------ | ------------------- | ------------------------ | +| `MRB_TT_FALSE` | FalseClass/NilClass | `nil` has `MRB_TT_FALSE` | +| `MRB_TT_TRUE` | TrueClass | | +| `MRB_TT_INTEGER` | Integer | Immediate value | +| `MRB_TT_FLOAT` | Float | May be immediate | +| `MRB_TT_SYMBOL` | Symbol | Immediate value | +| `MRB_TT_STRING` | String | Heap object | +| `MRB_TT_ARRAY` | Array | Heap object | +| `MRB_TT_HASH` | Hash | Heap object | +| `MRB_TT_OBJECT` | Object | User-defined classes | +| `MRB_TT_CLASS` | Class | | +| `MRB_TT_MODULE` | Module | | +| `MRB_TT_PROC` | Proc | | +| `MRB_TT_CDATA` | (C data) | Wrapped C structs | +| `MRB_TT_EXCEPTION` | Exception | | +| `MRB_TT_FIBER` | Fiber | | ## Defining Classes and Modules @@ -165,15 +165,15 @@ mrb_define_module_function(mrb, mod, "name", my_method, MRB_ARGS_ANY()); ### Argument Specifiers -| Macro | Meaning | -| ----- | ------- | -| `MRB_ARGS_NONE()` | No arguments | -| `MRB_ARGS_REQ(n)` | `n` required arguments | -| `MRB_ARGS_OPT(n)` | `n` optional arguments | -| `MRB_ARGS_ARG(r,o)` | `r` required + `o` optional | -| `MRB_ARGS_REST()` | Splat (`*args`) | -| `MRB_ARGS_BLOCK()` | Block (`&block`) | -| `MRB_ARGS_ANY()` | Any number (same as REST) | +| Macro | Meaning | +| ---------------------- | ------------------------------------- | +| `MRB_ARGS_NONE()` | No arguments | +| `MRB_ARGS_REQ(n)` | `n` required arguments | +| `MRB_ARGS_OPT(n)` | `n` optional arguments | +| `MRB_ARGS_ARG(r,o)` | `r` required + `o` optional | +| `MRB_ARGS_REST()` | Splat (`*args`) | +| `MRB_ARGS_BLOCK()` | Block (`&block`) | +| `MRB_ARGS_ANY()` | Any number (same as REST) | | `MRB_ARGS_KEY(n,rest)` | `n` keyword args, `rest`=1 for `**kw` | These can be combined with `|`: @@ -192,27 +192,27 @@ mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...); ### Format Specifiers -| Spec | Ruby Type | C Type(s) | Notes | -| ---- | --------- | --------- | ----- | -| `o` | any | `mrb_value` | No type check | -| `i` | Numeric | `mrb_int` | Coerces to integer | -| `f` | Numeric | `mrb_float` | Coerces to float | -| `b` | any | `mrb_bool` | Truthiness | -| `n` | String/Symbol | `mrb_sym` | Converts to symbol | -| `s` | String | `const char*, mrb_int` | Pointer + length | -| `z` | String | `const char*` | Null-terminated | -| `S` | String | `mrb_value` | String value | -| `A` | Array | `mrb_value` | Array value | -| `H` | Hash | `mrb_value` | Hash value | -| `C` | Class | `mrb_value` | Class/Module value | -| `c` | Class | `struct RClass*` | Class pointer | -| `a` | Array | `const mrb_value*, mrb_int` | Array pointer + length | -| `d` | C Data | `void*` | Requires `mrb_data_type*` | -| `&` | Block | `mrb_value` | Block argument | -| `*` | rest | `const mrb_value*, mrb_int` | Rest arguments | -| `\|` | — | — | Following args are optional | -| `?` | — | `mrb_bool` | Was previous optional arg given? | -| `:` | keywords | `mrb_kwargs` | Keyword arguments | +| Spec | Ruby Type | C Type(s) | Notes | +| ---- | ------------- | --------------------------- | -------------------------------- | +| `o` | any | `mrb_value` | No type check | +| `i` | Numeric | `mrb_int` | Coerces to integer | +| `f` | Numeric | `mrb_float` | Coerces to float | +| `b` | any | `mrb_bool` | Truthiness | +| `n` | String/Symbol | `mrb_sym` | Converts to symbol | +| `s` | String | `const char*, mrb_int` | Pointer + length | +| `z` | String | `const char*` | Null-terminated | +| `S` | String | `mrb_value` | String value | +| `A` | Array | `mrb_value` | Array value | +| `H` | Hash | `mrb_value` | Hash value | +| `C` | Class | `mrb_value` | Class/Module value | +| `c` | Class | `struct RClass*` | Class pointer | +| `a` | Array | `const mrb_value*, mrb_int` | Array pointer + length | +| `d` | C Data | `void*` | Requires `mrb_data_type*` | +| `&` | Block | `mrb_value` | Block argument | +| `*` | rest | `const mrb_value*, mrb_int` | Rest arguments | +| `\|` | — | — | Following args are optional | +| `?` | — | `mrb_bool` | Was previous optional arg given? | +| `:` | keywords | `mrb_kwargs` | Keyword arguments | Adding `!` to `S`, `A`, `H`, `C`, `c`, `s`, `z`, `a`, `d` allows `nil` (returns NULL/zero for nil). @@ -608,14 +608,14 @@ my_yield_method(mrb_state *mrb, mrb_value self) ### Fiber States -| State | Meaning | -| ----- | ------- | -| `MRB_FIBER_CREATED` | Created but not yet resumed | -| `MRB_FIBER_RUNNING` | Currently executing | -| `MRB_FIBER_RESUMED` | Resumed another fiber | -| `MRB_FIBER_SUSPENDED` | Yielded, waiting to resume | +| State | Meaning | +| ----------------------- | -------------------------------- | +| `MRB_FIBER_CREATED` | Created but not yet resumed | +| `MRB_FIBER_RUNNING` | Currently executing | +| `MRB_FIBER_RESUMED` | Resumed another fiber | +| `MRB_FIBER_SUSPENDED` | Yielded, waiting to resume | | `MRB_FIBER_TRANSFERRED` | Transferred via `Fiber#transfer` | -| `MRB_FIBER_TERMINATED` | Finished execution | +| `MRB_FIBER_TERMINATED` | Finished execution | **Limitation:** fibers cannot yield across C function boundaries. You cannot call `mrb_fiber_yield` from within a C-implemented @@ -644,13 +644,13 @@ mrb_ccontext_free(mrb, cxt); The `mrb_ccontext` structure provides several flags: -| Field | Purpose | -| ----- | ------- | +| Field | Purpose | +| ---------------- | --------------------------------------- | | `capture_errors` | Collect parse errors instead of raising | -| `no_exec` | Compile without executing (get RProc) | -| `no_optimize` | Disable peephole optimizations | -| `no_ext_ops` | Disable extended operand instructions | -| `keep_lv` | Preserve local variables across loads | +| `no_exec` | Compile without executing (get RProc) | +| `no_optimize` | Disable peephole optimizations | +| `no_ext_ops` | Disable extended operand instructions | +| `keep_lv` | Preserve local variables across loads | ### Loading with Context @@ -843,14 +843,14 @@ $ build/host/bin/mruby-config --libs # libraries Key macros that affect ABI: -| Macro | Effect | -| ----- | ------ | -| `MRB_NO_BOXING` | Struct-based values (larger, debuggable) | -| `MRB_WORD_BOXING` | Single-word values (fast, 32-bit safe) | -| `MRB_NAN_BOXING` | NaN-tagged values (default on 32-bit) | -| `MRB_NO_FLOAT` | Disable Float support | -| `MRB_INT64` | 64-bit integers | -| `MRB_USE_FLOAT32` | 32-bit floats | +| Macro | Effect | +| ----------------- | ---------------------------------------- | +| `MRB_NO_BOXING` | Struct-based values (larger, debuggable) | +| `MRB_WORD_BOXING` | Single-word values (fast, 32-bit safe) | +| `MRB_NAN_BOXING` | NaN-tagged values (default on 32-bit) | +| `MRB_NO_FLOAT` | Disable Float support | +| `MRB_INT64` | 64-bit integers | +| `MRB_USE_FLOAT32` | 32-bit floats | Mismatching these between library and application causes silent data corruption. diff --git a/doc/guides/language.md b/doc/guides/language.md index 81627dbfe..31c9b074d 100644 --- a/doc/guides/language.md +++ b/doc/guides/language.md @@ -205,11 +205,11 @@ mruby's numeric type sizes depend on the boxing mode and platform. ### Integer -| Configuration | Range | -| ------------- | ----- | +| Configuration | Range | +| -------------------------------------- | ---------------- | | 64-bit word boxing (default on 64-bit) | roughly +/- 2^62 | | 32-bit word boxing (default on 32-bit) | roughly +/- 2^30 | -| NaN boxing (64-bit only) | -2^31 to 2^31-1 | +| NaN boxing (64-bit only) | -2^31 to 2^31-1 | Integer overflow raises a `RangeError` unless the `mruby-bigint` gem is included, in which case integers automatically promote to @@ -235,32 +235,32 @@ With word boxing on 64-bit, many float values are stored inline These classes are always available in mruby (no gem required): -| Class | Notes | -| ----- | ----- | -| Object | Base class for all objects | -| Module | Module definition and mixin | -| Class | Class definition and instantiation | -| NilClass | Singleton `nil` | -| TrueClass | Singleton `true` | -| FalseClass | Singleton `false` | -| Integer | Fixed-precision integer | -| Float | Floating-point (unless `MRB_NO_FLOAT`) | -| Symbol | Interned identifier | -| String | Mutable byte string | -| Array | Ordered collection | -| Hash | Key-value mapping | -| Range | Interval representation | -| Proc | Closure / callable object | -| Exception | Exception hierarchy root | -| StandardError | Common error base | +| Class | Notes | +| ------------- | -------------------------------------- | +| Object | Base class for all objects | +| Module | Module definition and mixin | +| Class | Class definition and instantiation | +| NilClass | Singleton `nil` | +| TrueClass | Singleton `true` | +| FalseClass | Singleton `false` | +| Integer | Fixed-precision integer | +| Float | Floating-point (unless `MRB_NO_FLOAT`) | +| Symbol | Interned identifier | +| String | Mutable byte string | +| Array | Ordered collection | +| Hash | Key-value mapping | +| Range | Interval representation | +| Proc | Closure / callable object | +| Exception | Exception hierarchy root | +| StandardError | Common error base | ### Core Modules -| Module | Notes | -| ------ | ----- | -| Kernel | Core methods (`puts`, `p`, `raise`, etc.) | -| Comparable | Comparison operators via `<=>` | -| Enumerable | Collection iteration methods | +| Module | Notes | +| ---------- | ----------------------------------------- | +| Kernel | Core methods (`puts`, `p`, `raise`, etc.) | +| Comparable | Comparison operators via `<=>` | +| Enumerable | Collection iteration methods | ## Standard Library (via gemboxes) @@ -270,70 +270,70 @@ gembox provides the class or feature you need: ### Classes and Modules -| Class/Module | Gembox | Gem | -| ------------ | ------ | --- | -| Fiber | stdlib | mruby-fiber | -| Enumerator | stdlib | mruby-enumerator | -| Enumerator::Lazy | stdlib | mruby-enum-lazy | -| Set | stdlib | mruby-set | -| ObjectSpace | stdlib | mruby-objectspace | -| Time | stdlib-ext | mruby-time | -| Struct | stdlib-ext | mruby-struct | -| Data | stdlib-ext | mruby-data | -| Random | stdlib-ext | mruby-random | -| IO, File | stdlib-io | mruby-io | -| Socket | stdlib-io | mruby-socket | -| Dir | stdlib-io | mruby-dir | -| Errno | stdlib-io | mruby-errno | -| Math | math | mruby-math | -| Rational | math | mruby-rational | -| Complex | math | mruby-complex | -| Bigint | math | mruby-bigint | -| Method, UnboundMethod | metaprog | mruby-method | +| Class/Module | Gembox | Gem | +| --------------------- | ---------- | ----------------- | +| Fiber | stdlib | mruby-fiber | +| Enumerator | stdlib | mruby-enumerator | +| Enumerator::Lazy | stdlib | mruby-enum-lazy | +| Set | stdlib | mruby-set | +| ObjectSpace | stdlib | mruby-objectspace | +| Time | stdlib-ext | mruby-time | +| Struct | stdlib-ext | mruby-struct | +| Data | stdlib-ext | mruby-data | +| Random | stdlib-ext | mruby-random | +| IO, File | stdlib-io | mruby-io | +| Socket | stdlib-io | mruby-socket | +| Dir | stdlib-io | mruby-dir | +| Errno | stdlib-io | mruby-errno | +| Math | math | mruby-math | +| Rational | math | mruby-rational | +| Complex | math | mruby-complex | +| Bigint | math | mruby-bigint | +| Method, UnboundMethod | metaprog | mruby-method | ### Methods and Features -| Feature | Gembox | Gem | -| ------- | ------ | --- | -| `catch`/`throw` | stdlib | mruby-catch | -| `Kernel#sprintf`, `String#%` | stdlib-ext | mruby-sprintf | -| `Array#pack`, `String#unpack` | stdlib-ext | mruby-pack | -| `Kernel#rand` | stdlib-ext | mruby-random | -| `Kernel#eval` | metaprog | mruby-eval | -| `Kernel#binding` | metaprog | mruby-binding | -| `Proc#binding` | metaprog | mruby-proc-binding | -| Runtime compiler | metaprog | mruby-compiler | +| Feature | Gembox | Gem | +| ----------------------------- | ---------- | ------------------ | +| `catch`/`throw` | stdlib | mruby-catch | +| `Kernel#sprintf`, `String#%` | stdlib-ext | mruby-sprintf | +| `Array#pack`, `String#unpack` | stdlib-ext | mruby-pack | +| `Kernel#rand` | stdlib-ext | mruby-random | +| `Kernel#eval` | metaprog | mruby-eval | +| `Kernel#binding` | metaprog | mruby-binding | +| `Proc#binding` | metaprog | mruby-proc-binding | +| Runtime compiler | metaprog | mruby-compiler | ### Core Class Extensions The `stdlib` gembox also extends built-in classes with additional methods. These are included by default: -| Extension | Examples | -| --------- | -------- | -| Array extensions | `#dig`, `#union`, `#difference` | -| Hash extensions | `#dig`, `#transform_keys`, `#transform_values` | -| String extensions | `#encode`, `#bytes`, `#chars` | -| Numeric extensions | `Integer#digits`, `Integer#pow` | -| Comparable extensions | `#clamp` | -| Enumerable extensions | `#sort_by`, `#min_by`, `#max_by`, `#tally` | -| Range extensions | `#size`, `#cover?` | -| Proc extensions | `#<<`, `#>>` (composition) | -| Symbol extensions | `#to_proc` | -| Object extensions | `#then`, `#yield_self` | -| Kernel extensions | `#__method__` | -| Class/Module extensions | `Module#name` | +| Extension | Examples | +| ----------------------- | ---------------------------------------------- | +| Array extensions | `#dig`, `#union`, `#difference` | +| Hash extensions | `#dig`, `#transform_keys`, `#transform_values` | +| String extensions | `#encode`, `#bytes`, `#chars` | +| Numeric extensions | `Integer#digits`, `Integer#pow` | +| Comparable extensions | `#clamp` | +| Enumerable extensions | `#sort_by`, `#min_by`, `#max_by`, `#tally` | +| Range extensions | `#size`, `#cover?` | +| Proc extensions | `#<<`, `#>>` (composition) | +| Symbol extensions | `#to_proc` | +| Object extensions | `#then`, `#yield_self` | +| Kernel extensions | `#__method__` | +| Class/Module extensions | `Module#name` | ### Gembox Summary -| Gembox | Contents | Notes | -| ------ | -------- | ----- | -| `stdlib` | Core class extensions, Fiber, Enumerator, Set | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` | -| `stdlib-ext` | Time, Struct, Data, Random, sprintf, pack | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` | -| `stdlib-io` | IO, File, Dir, Socket, Errno | Requires stdio | -| `math` | Math, Rational, Complex, Bigint | Works with `MRB_NO_STDIO` | -| `metaprog` | eval, binding, Method, compiler | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` | -| `default` | All of the above + CLI tools | Full installation | +| Gembox | Contents | Notes | +| ------------ | --------------------------------------------- | -------------------------------------------- | +| `stdlib` | Core class extensions, Fiber, Enumerator, Set | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` | +| `stdlib-ext` | Time, Struct, Data, Random, sprintf, pack | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` | +| `stdlib-io` | IO, File, Dir, Socket, Errno | Requires stdio | +| `math` | Math, Rational, Complex, Bigint | Works with `MRB_NO_STDIO` | +| `metaprog` | eval, binding, Method, compiler | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` | +| `default` | All of the above + CLI tools | Full installation | ## Key Differences from CRuby @@ -378,8 +378,8 @@ This means subclassing `Array` or `String` and adding `@fields` will raise an er ### Operator Overriding -Operators of primitive classes cannot be overridden by user code. -Redefining `String#+` has no effect on the behavior of the `+` __operator__. +Operators of primitive classes cannot be overridden by user code. +Redefining `String#+` has no effect on the behavior of the `+` operator. ### Module Loading Hooks @@ -416,15 +416,15 @@ differently on 32-bit or NaN boxing configurations. Key compile-time macros that affect language behavior: -| Macro | Effect | -| ----- | ------ | -| `MRB_NO_FLOAT` | Remove all float support | -| `MRB_USE_FLOAT32` | Use 32-bit float instead of double | -| `MRB_UTF8_STRING` | Enable UTF-8 string handling | -| `MRB_INT32` | Force 32-bit integer | -| `MRB_INT64` | Force 64-bit integer | -| `MRB_STR_LENGTH_MAX` | Max string length (default 1MB) | -| `MRB_ARY_LENGTH_MAX` | Max array length (default 2^17) | +| Macro | Effect | +| -------------------- | ---------------------------------- | +| `MRB_NO_FLOAT` | Remove all float support | +| `MRB_USE_FLOAT32` | Use 32-bit float instead of double | +| `MRB_UTF8_STRING` | Enable UTF-8 string handling | +| `MRB_INT32` | Force 32-bit integer | +| `MRB_INT64` | Force 64-bit integer | +| `MRB_STR_LENGTH_MAX` | Max string length (default 1MB) | +| `MRB_ARY_LENGTH_MAX` | Max array length (default 2^17) | See [mrbconf.md](mrbconf.md) for the complete list of configuration macros. diff --git a/doc/guides/memory.md b/doc/guides/memory.md index c48945daf..5f3652850 100644 --- a/doc/guides/memory.md +++ b/doc/guides/memory.md @@ -202,10 +202,10 @@ any other heap page. The only differences are: The page size is controlled by `MRB_HEAP_PAGE_SIZE` (default: 1024 slots). Each page occupies: -| Platform | Slot size | Page size (approx) | -|----------|-----------|---------------------| -| 64-bit | 40 bytes | ~41 KB | -| 32-bit | 24 bytes | ~25 KB | +| Platform | Slot size | Page size (approx) | +| -------- | --------- | ------------------ | +| 64-bit | 40 bytes | ~41 KB | +| 32-bit | 24 bytes | ~25 KB | To estimate pages for a given buffer: `pages = buffer_size / sizeof(mrb_heap_page)`. Each page provides `MRB_HEAP_PAGE_SIZE` object slots. diff --git a/doc/guides/rom-method-table.md b/doc/guides/rom-method-table.md index f15b9a29b..0e7f7f0c0 100644 --- a/doc/guides/rom-method-table.md +++ b/doc/guides/rom-method-table.md @@ -79,7 +79,6 @@ Include `` (which provides `mrb_mt_entry`, ```c #include -#include static const mrb_mt_entry my_rom_entries[] = { MRB_MT_ENTRY(my_method_a, MRB_SYM(method_a), MRB_ARGS_REQ(1)), diff --git a/doc/internal/architecture.md b/doc/internal/architecture.md index b57e95561..438dc823d 100644 --- a/doc/internal/architecture.md +++ b/doc/internal/architecture.md @@ -31,17 +31,17 @@ struct RBasic (8 bytes on 64-bit) All object structs embed this header via `MRB_OBJECT_HEADER`: -| Struct | Ruby Type | Extra Fields | -| ------ | --------- | ------------ | -| `RObject` | Object instances | `iv` (instance variables) | -| `RClass` | Class/Module | `iv`, `mt` (method table), `super` | -| `RString` | String | embedded or heap buffer, length | -| `RArray` | Array | embedded or heap buffer, length | -| `RHash` | Hash | hash table or k-v array | -| `RProc` | Proc/Lambda | `irep` or C function, environment | -| `RData` | C data wrapper | `void *data`, `mrb_data_type` | -| `RFiber` | Fiber | `mrb_context` | -| `RException` | Exception | `iv` | +| Struct | Ruby Type | Extra Fields | +| ------------ | ---------------- | ---------------------------------- | +| `RObject` | Object instances | `iv` (instance variables) | +| `RClass` | Class/Module | `iv`, `mt` (method table), `super` | +| `RString` | String | embedded or heap buffer, length | +| `RArray` | Array | embedded or heap buffer, length | +| `RHash` | Hash | hash table or k-v array | +| `RProc` | Proc/Lambda | `irep` or C function, environment | +| `RData` | C data wrapper | `void *data`, `mrb_data_type` | +| `RFiber` | Fiber | `mrb_context` | +| `RException` | Exception | `iv` | Immediate values (Integer, Symbol, `true`, `false`, `nil`) are encoded directly in `mrb_value` without heap allocation. The encoding depends on @@ -111,52 +111,52 @@ See [compiler.md](compiler.md) for detailed compiler internals, ### Core (`src/`) -| File | Responsibility | -| ---- | -------------- | -| `vm.c` | Bytecode dispatch loop, method invocation | -| `state.c` | `mrb_state` init/close, irep management | -| `gc.c` | Garbage collector (mark-sweep, incremental) | -| `class.c` | Class/module definition, method tables | -| `object.c` | Core object operations | -| `variable.c` | Instance/class/global variables, object shapes | -| `proc.c` | Proc/Lambda/closure handling | -| `array.c` | Array implementation | -| `string.c` | String implementation (embedded, shared, heap) | -| `hash.c` | Hash implementation (open addressing) | -| `numeric.c` | Integer/Float arithmetic | -| `symbol.c` | Symbol table and interning | -| `range.c` | Range implementation | -| `error.c` | Exception creation, raise, backtrace | -| `kernel.c` | Kernel module methods | -| `load.c` | `.mrb` bytecode loading | -| `dump.c` | Bytecode serialization (write `.mrb`) | -| `print.c` | Print/puts/p output | -| `backtrace.c` | Stack trace generation | +| File | Responsibility | +| ------------- | ---------------------------------------------- | +| `vm.c` | Bytecode dispatch loop, method invocation | +| `state.c` | `mrb_state` init/close, irep management | +| `gc.c` | Garbage collector (mark-sweep, incremental) | +| `class.c` | Class/module definition, method tables | +| `object.c` | Core object operations | +| `variable.c` | Instance/class/global variables, object shapes | +| `proc.c` | Proc/Lambda/closure handling | +| `array.c` | Array implementation | +| `string.c` | String implementation (embedded, shared, heap) | +| `hash.c` | Hash implementation (open addressing) | +| `numeric.c` | Integer/Float arithmetic | +| `symbol.c` | Symbol table and interning | +| `range.c` | Range implementation | +| `error.c` | Exception creation, raise, backtrace | +| `kernel.c` | Kernel module methods | +| `load.c` | `.mrb` bytecode loading | +| `dump.c` | Bytecode serialization (write `.mrb`) | +| `print.c` | Print/puts/p output | +| `backtrace.c` | Stack trace generation | ### Compiler (`mrbgems/mruby-compiler/core/`) -| File | Responsibility | -| ---- | -------------- | -| `parse.y` | Yacc grammar → AST | -| `y.tab.c` | Generated parser (from parse.y) | -| `codegen.c` | AST → bytecode (irep) | -| `node.h` | AST node type definitions | +| File | Responsibility | +| ----------- | ------------------------------- | +| `parse.y` | Yacc grammar → AST | +| `y.tab.c` | Generated parser (from parse.y) | +| `codegen.c` | AST → bytecode (irep) | +| `node.h` | AST node type definitions | ### Key Headers (`include/mruby/`) -| Header | Contents | -| ------ | -------- | -| `mruby.h` | `mrb_state`, core API declarations | -| `value.h` | `mrb_value`, type enums, value macros | -| `object.h` | `RBasic`, `RObject`, object header | -| `class.h` | `RClass`, method table types | -| `string.h` | `RString`, string macros | -| `array.h` | `RArray`, array macros | -| `hash.h` | `RHash`, hash API | -| `data.h` | `RData`, C data wrapping | -| `irep.h` | `mrb_irep`, bytecode structures | -| `compile.h` | Compiler context, `mrb_load_string` | -| `boxing_*.h` | Value boxing implementations | +| Header | Contents | +| ------------ | ------------------------------------- | +| `mruby.h` | `mrb_state`, core API declarations | +| `value.h` | `mrb_value`, type enums, value macros | +| `object.h` | `RBasic`, `RObject`, object header | +| `class.h` | `RClass`, method table types | +| `string.h` | `RString`, string macros | +| `array.h` | `RArray`, array macros | +| `hash.h` | `RHash`, hash API | +| `data.h` | `RData`, C data wrapping | +| `irep.h` | `mrb_irep`, bytecode structures | +| `compile.h` | Compiler context, `mrb_load_string` | +| `boxing_*.h` | Value boxing implementations | ## mrbgems System diff --git a/doc/internal/boxing.md b/doc/internal/boxing.md index 33dcbd860..653d8c3a1 100644 --- a/doc/internal/boxing.md +++ b/doc/internal/boxing.md @@ -77,16 +77,16 @@ No boxing represents `mrb_value` by the C struct with `type` and the value union ## Comparison -| Property | Word Boxing | NaN Boxing | No Boxing | -| ---------------------- | ------------------ | ------------------ | -------------------- | -| `mrb_value` size | 1 word (4/8 byte) | 8 bytes | 2 words (8/16 bytes) | -| Default on | most platforms | (manual opt-in) | `host-debug` | -| Macro | `MRB_WORD_BOXING` | `MRB_NAN_BOXING` | `MRB_NO_BOXING` | -| Inline integers | yes (31/63 bit) | yes (32 bit) | yes (full width) | -| Inline floats (64-bit) | yes (rotation) | yes (native) | yes (struct field) | -| Inline floats (32-bit) | no (heap RFloat) | yes (native) | yes (struct field) | -| Pointer size limit | none | 48 bits | none | -| Debugger friendly | no | no | yes | +| Property | Word Boxing | NaN Boxing | No Boxing | +| ---------------------- | ----------------- | ---------------- | -------------------- | +| `mrb_value` size | 1 word (4/8 byte) | 8 bytes | 2 words (8/16 bytes) | +| Default on | most platforms | (manual opt-in) | `host-debug` | +| Macro | `MRB_WORD_BOXING` | `MRB_NAN_BOXING` | `MRB_NO_BOXING` | +| Inline integers | yes (31/63 bit) | yes (32 bit) | yes (full width) | +| Inline floats (64-bit) | yes (rotation) | yes (native) | yes (struct field) | +| Inline floats (32-bit) | no (heap RFloat) | yes (native) | yes (struct field) | +| Pointer size limit | none | 48 bits | none | +| Debugger friendly | no | no | yes | ## ABI Compatibility diff --git a/doc/internal/compiler.md b/doc/internal/compiler.md index 92cbac614..7f83ab16f 100644 --- a/doc/internal/compiler.md +++ b/doc/internal/compiler.md @@ -40,18 +40,18 @@ file: `mrbgems/mruby-compiler/core/parse.y`. The parser maintains extensive state in `mrb_parser_state`: -- **lstate**: current lexer state (EXPR\_BEG, EXPR\_END, EXPR\_ARG, - EXPR\_DOT, EXPR\_FNAME, etc.). Controls how tokens like `+`/`-` +- **lstate**: current lexer state (EXPR_BEG, EXPR_END, EXPR_ARG, + EXPR_DOT, EXPR_FNAME, etc.). Controls how tokens like `+`/`-` are interpreted (sign vs operator) and whether newlines are significant. - **locals**: stack of local variable lists (one per scope), stored as cons-lists of symbols. -- **lex\_strterm**: string/heredoc parsing state for handling nested +- **lex_strterm**: string/heredoc parsing state for handling nested interpolation. -- **cond\_stack**, **cmdarg\_stack**: bit stacks tracking +- **cond_stack**, **cmdarg_stack**: bit stacks tracking conditional and command argument contexts. - **tree**: root AST node after successful parse. -- **error\_buffer**: accumulated parse errors. +- **error_buffer**: accumulated parse errors. ### AST Nodes @@ -123,10 +123,10 @@ reuse temporaries within an expression. Instructions are emitted via helper functions: - `genop_0(opcode)`: no operands -- `genop_1(opcode, a)`: one operand (auto-extends with OP\_EXT1 +- `genop_1(opcode, a)`: one operand (auto-extends with OP_EXT1 if a > 255) - `genop_2(opcode, a, b)`: two operands (auto-extends with - OP\_EXT1/2/3 as needed) + OP_EXT1/2/3 as needed) - `genop_3(opcode, a, b, c)`: three operands - `genop_W(opcode, a)`: 24-bit operand - `genop_2S(opcode, a, b)`: one 8-bit + one 16-bit operand @@ -176,14 +176,14 @@ mrb_irep Pool entries store constants referenced by instructions: -| Type | Tag | Description | -| ---- | --- | ----------- | -| `IREP_TT_STR` | 0 | Dynamic string (heap allocated) | -| `IREP_TT_SSTR` | 2 | Static string (read-only) | -| `IREP_TT_INT32` | 1 | 32-bit integer | -| `IREP_TT_INT64` | 3 | 64-bit integer | -| `IREP_TT_FLOAT` | 5 | Floating-point number | -| `IREP_TT_BIGINT` | 7 | Arbitrary-precision integer | +| Type | Tag | Description | +| ---------------- | --- | ------------------------------- | +| `IREP_TT_STR` | 0 | Dynamic string (heap allocated) | +| `IREP_TT_SSTR` | 2 | Static string (read-only) | +| `IREP_TT_INT32` | 1 | 32-bit integer | +| `IREP_TT_INT64` | 3 | 64-bit integer | +| `IREP_TT_FLOAT` | 5 | Floating-point number | +| `IREP_TT_BIGINT` | 7 | Arbitrary-precision integer | The code generator deduplicates pool entries: identical strings and equal numeric values share the same pool index. @@ -209,28 +209,28 @@ During exception unwinding, handlers are searched in reverse order Standard instructions use 8-bit operands. When a value exceeds 255, extension prefixes widen operands to 16 bits: -| Prefix | Effect | -| ------ | ------ | -| `OP_EXT1` | First operand (a) becomes 16-bit | +| Prefix | Effect | +| --------- | --------------------------------- | +| `OP_EXT1` | First operand (a) becomes 16-bit | | `OP_EXT2` | Second operand (b) becomes 16-bit | -| `OP_EXT3` | Both a and b become 16-bit | +| `OP_EXT3` | Both a and b become 16-bit | Instruction formats: -| Format | Layout | Size | -| ------ | ------ | ---- | -| Z | opcode only | 1 byte | -| B | opcode + a(8) | 2 bytes | -| BB | opcode + a(8) + b(8) | 3 bytes | -| BBB | opcode + a(8) + b(8) + c(8) | 4 bytes | -| BS | opcode + a(8) + b(16) | 4 bytes | -| BSS | opcode + a(8) + b(16) + c(16) | 6 bytes | -| S | opcode + a(16) | 3 bytes | -| W | opcode + a(24) | 4 bytes | +| Format | Layout | Size | +| ------ | ----------------------------- | ------- | +| Z | opcode only | 1 byte | +| B | opcode + a(8) | 2 bytes | +| BB | opcode + a(8) + b(8) | 3 bytes | +| BBB | opcode + a(8) + b(8) + c(8) | 4 bytes | +| BS | opcode + a(8) + b(16) | 4 bytes | +| BSS | opcode + a(8) + b(16) + c(16) | 6 bytes | +| S | opcode + a(16) | 3 bytes | +| W | opcode + a(24) | 4 bytes | See [opcode.md](opcode.md) for the full instruction table. -## OP\_ENTER: Argument Specification +## OP_ENTER: Argument Specification `OP_ENTER` encodes a method's argument layout in a 24-bit value (W format). The bit fields are defined by the `MRB_ARGS_*` macros: @@ -258,16 +258,16 @@ string interning for common symbols. Generated by `lib/mruby/presym.rb`, the presym table maps symbol names to compile-time constants: -| Macro | Example | Symbol | -| ----- | ------- | ------ | -| `MRB_SYM(name)` | `MRB_SYM(initialize)` | `:initialize` | -| `MRB_SYM_B(name)` | `MRB_SYM_B(map)` | `:map!` | -| `MRB_SYM_Q(name)` | `MRB_SYM_Q(nil)` | `:nil?` | -| `MRB_SYM_E(name)` | `MRB_SYM_E(name)` | `:name=` | -| `MRB_OPSYM(op)` | `MRB_OPSYM(add)` | `:+` | -| `MRB_IVSYM(name)` | `MRB_IVSYM(name)` | `:@name` | -| `MRB_CVSYM(name)` | `MRB_CVSYM(count)` | `:@@count` | -| `MRB_GVSYM(name)` | `MRB_GVSYM(stdout)` | `:$stdout` | +| Macro | Example | Symbol | +| ----------------- | --------------------- | ------------- | +| `MRB_SYM(name)` | `MRB_SYM(initialize)` | `:initialize` | +| `MRB_SYM_B(name)` | `MRB_SYM_B(map)` | `:map!` | +| `MRB_SYM_Q(name)` | `MRB_SYM_Q(nil)` | `:nil?` | +| `MRB_SYM_E(name)` | `MRB_SYM_E(name)` | `:name=` | +| `MRB_OPSYM(op)` | `MRB_OPSYM(add)` | `:+` | +| `MRB_IVSYM(name)` | `MRB_IVSYM(name)` | `:@name` | +| `MRB_CVSYM(name)` | `MRB_CVSYM(count)` | `:@@count` | +| `MRB_GVSYM(name)` | `MRB_GVSYM(stdout)` | `:$stdout` | ## Binary Format (.mrb) @@ -299,25 +299,25 @@ mrbc -Boutput source.rb # C array format ## Compilation Limits -| Limit | Value | -| ----- | ----- | -| Max nesting depth | 256 (`MRB_CODEGEN_LEVEL_MAX`) | -| Max local variables | 255 (uint16 `nlocals`) | -| Max symbols per irep | 65535 | -| Max operand (standard) | 255 (8-bit) | -| Max operand (extended) | 65535 (16-bit) | +| Limit | Value | +| ---------------------- | ----------------------------- | +| Max nesting depth | 256 (`MRB_CODEGEN_LEVEL_MAX`) | +| Max local variables | 255 (uint16 `nlocals`) | +| Max symbols per irep | 65535 | +| Max operand (standard) | 255 (8-bit) | +| Max operand (extended) | 65535 (16-bit) | ## Source Files -| File | Contents | -| ---- | -------- | -| `mrbgems/mruby-compiler/core/parse.y` | Lrama/Bison grammar | -| `mrbgems/mruby-compiler/core/y.tab.c` | Generated parser | -| `mrbgems/mruby-compiler/core/codegen.c` | Code generator | -| `mrbgems/mruby-compiler/core/node.h` | AST node types | -| `include/mruby/irep.h` | IRep structure definition | -| `include/mruby/compile.h` | Compiler context API | -| `include/mruby/ops.h` | Opcode definitions | -| `src/load.c` | Binary format loader | -| `src/dump.c` | Binary format writer | -| `lib/mruby/presym.rb` | Presym table generator | +| File | Contents | +| --------------------------------------- | ------------------------- | +| `mrbgems/mruby-compiler/core/parse.y` | Lrama/Bison grammar | +| `mrbgems/mruby-compiler/core/y.tab.c` | Generated parser | +| `mrbgems/mruby-compiler/core/codegen.c` | Code generator | +| `mrbgems/mruby-compiler/core/node.h` | AST node types | +| `include/mruby/irep.h` | IRep structure definition | +| `include/mruby/compile.h` | Compiler context API | +| `include/mruby/ops.h` | Opcode definitions | +| `src/load.c` | Binary format loader | +| `src/dump.c` | Binary format writer | +| `lib/mruby/presym.rb` | Presym table generator | diff --git a/doc/internal/gc.md b/doc/internal/gc.md index 87cc264fe..3171bcbe1 100644 --- a/doc/internal/gc.md +++ b/doc/internal/gc.md @@ -26,12 +26,12 @@ pauses. Every heap-allocated object has a color stored in `RBasic::gc_color` (3 bits): -| Color | Value | Meaning | -| ----- | ----- | ------- | -| White (A or B) | 1 or 2 | Unmarked, candidate for collection | -| Gray | 0 | Marked, but children not yet scanned | -| Black | 4 | Fully marked and scanned | -| Red | 7 | Static/ROM object, never collected | +| Color | Value | Meaning | +| -------------- | ------ | ------------------------------------ | +| White (A or B) | 1 or 2 | Unmarked, candidate for collection | +| Gray | 0 | Marked, but children not yet scanned | +| Black | 4 | Fully marked and scanned | +| Red | 7 | Static/ROM object, never collected | The GC uses two white types (A and B) in a flip-flop scheme. At the start of each GC cycle, the meaning of "current white" is flipped by @@ -107,7 +107,7 @@ The GC operates as a three-state machine: GC_STATE_ROOT --> GC_STATE_MARK --> GC_STATE_SWEEP --> GC_STATE_ROOT ``` -### Root Scan (GC\_STATE\_ROOT) +### Root Scan (GC_STATE_ROOT) Marks objects directly reachable from the VM: @@ -121,7 +121,7 @@ Marks objects directly reachable from the VM: After root scanning, the white color is flipped. -### Incremental Marking (GC\_STATE\_MARK) +### Incremental Marking (GC_STATE_MARK) Gray objects are popped from the gray stack and their children marked. Each step processes a limited number of objects: @@ -137,7 +137,7 @@ When the gray stack is exhausted, the final marking phase re-marks the arena and global variables to catch objects created during marking, then transitions to sweep. -### Sweep (GC\_STATE\_SWEEP) +### Sweep (GC_STATE_SWEEP) Iterates through heap pages. For each object: @@ -325,15 +325,15 @@ From Ruby: `GC.start`. ### Compile-Time -| Macro | Default | Description | -| ----- | ------- | ----------- | -| `MRB_HEAP_PAGE_SIZE` | 1024 | Objects per heap page | -| `MRB_GRAY_STACK_SIZE` | 1024 | Gray stack capacity | -| `MRB_GC_ARENA_SIZE` | 100 | Arena size (fixed mode) or initial size | -| `MRB_GC_FIXED_ARENA` | off | Use fixed-size arena | -| `MRB_GC_TURN_OFF_GENERATIONAL` | off | Disable generational mode | -| `MRB_GC_STRESS` | off | Full GC on every allocation (debug) | -| `MRB_USE_MALLOC_TRIM` | off | Call `malloc_trim()` after full GC | +| Macro | Default | Description | +| ------------------------------ | ------- | --------------------------------------- | +| `MRB_HEAP_PAGE_SIZE` | 1024 | Objects per heap page | +| `MRB_GRAY_STACK_SIZE` | 1024 | Gray stack capacity | +| `MRB_GC_ARENA_SIZE` | 100 | Arena size (fixed mode) or initial size | +| `MRB_GC_FIXED_ARENA` | off | Use fixed-size arena | +| `MRB_GC_TURN_OFF_GENERATIONAL` | off | Disable generational mode | +| `MRB_GC_STRESS` | off | Full GC on every allocation (debug) | +| `MRB_USE_MALLOC_TRIM` | off | Call `malloc_trim()` after full GC | ### Runtime @@ -350,8 +350,8 @@ GC.disable # disable GC ## Source Files -| File | Contents | -| ---- | -------- | -| `src/gc.c` | GC implementation (~1400 lines) | +| File | Contents | +| -------------------- | --------------------------------- | +| `src/gc.c` | GC implementation (~1400 lines) | | `include/mruby/gc.h` | `mrb_gc` structure, public GC API | -| `include/mruby.h` | Arena save/restore macros | +| `include/mruby.h` | Arena save/restore macros | diff --git a/doc/internal/vm.md b/doc/internal/vm.md index bbbf4338f..10af1a282 100644 --- a/doc/internal/vm.md +++ b/doc/internal/vm.md @@ -97,12 +97,12 @@ return n + 1 (skip self) ### Call Context Info (cci) -| Value | Name | Meaning | -| ----- | ---- | ------- | -| 0 | `CINFO_NONE` | Normal VM-to-VM call | -| 1 | `CINFO_DIRECT` | Explicit VM call (block, lambda.call) | -| 2 | `CINFO_SKIP` | Skip frame in stack traces | -| 3 | `CINFO_RESUMED` | Fiber resumed (stop execution) | +| Value | Name | Meaning | +| ----- | --------------- | ------------------------------------- | +| 0 | `CINFO_NONE` | Normal VM-to-VM call | +| 1 | `CINFO_DIRECT` | Explicit VM call (block, lambda.call) | +| 2 | `CINFO_SKIP` | Skip frame in stack traces | +| 3 | `CINFO_RESUMED` | Fiber resumed (stop execution) | ## Dispatch Loop @@ -241,13 +241,13 @@ correctness. ### Proc Types -| Flag | Meaning | -| ---- | ------- | -| `MRB_PROC_CFUNC_FL` | C function (not irep-based) | -| `MRB_PROC_STRICT` | Lambda (strict argument check) | -| `MRB_PROC_ORPHAN` | No environment attachment | -| `MRB_PROC_ENVSET` | Has captured environment | -| `MRB_PROC_SCOPE` | Defines a new variable scope | +| Flag | Meaning | +| ------------------- | ------------------------------ | +| `MRB_PROC_CFUNC_FL` | C function (not irep-based) | +| `MRB_PROC_STRICT` | Lambda (strict argument check) | +| `MRB_PROC_ORPHAN` | No environment attachment | +| `MRB_PROC_ENVSET` | Has captured environment | +| `MRB_PROC_SCOPE` | Defines a new variable scope | ## Fiber Switching @@ -317,9 +317,9 @@ ensuring the incremental GC correctly tracks live references. ## Source Files -| File | Contents | -| ---- | -------- | -| `src/vm.c` | Dispatch loop, method invocation (~1900 lines) | -| `include/mruby.h` | `mrb_state`, `mrb_callinfo`, `mrb_context` | -| `include/mruby/proc.h` | `RProc`, `REnv` structures | -| `include/mruby/throw.h` | `MRB_TRY`/`MRB_CATCH` macros | +| File | Contents | +| ----------------------- | ---------------------------------------------- | +| `src/vm.c` | Dispatch loop, method invocation (~1900 lines) | +| `include/mruby.h` | `mrb_state`, `mrb_callinfo`, `mrb_context` | +| `include/mruby/proc.h` | `RProc`, `REnv` structures | +| `include/mruby/throw.h` | `MRB_TRY`/`MRB_CATCH` macros | diff --git a/doc/limitations.md b/doc/limitations.md index 575ddf00b..5d7a3181f 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -274,11 +274,11 @@ enabled with the `MRB_UTF8_STRING` compile flag. Integer size depends on the value boxing configuration: -| Configuration | Integer range | -| ------------- | ------------- | +| Configuration | Integer range | +| ----------------------------- | ---------------- | | Word boxing, 64-bit (default) | roughly +/- 2^62 | | Word boxing, 32-bit (default) | roughly +/- 2^30 | -| NaN boxing (64-bit only) | -2^31 to 2^31-1 | +| NaN boxing (64-bit only) | -2^31 to 2^31-1 | Code relying on 64-bit integer precision may behave differently across configurations. The `mruby-bigint` gem provides diff --git a/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c b/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c index 3cfc717b0..1174968ef 100644 --- a/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c +++ b/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c @@ -15,11 +15,6 @@ */ #include -/* - * The "mruby/presym.h" file is placed at the end of the mruby header file. - */ -#include - /* * Define your own struct RBigint. * diff --git a/include/mruby.h b/include/mruby.h index 1c12df08e..1c6e8385a 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1015,7 +1015,7 @@ typedef const char *mrb_args_format; * mrb_value str, kw_rest; * uint32_t kw_num = 3; * uint32_t kw_required = 1; - * // Note that `#include ` is required beforehand because `MRB_SYM()` is used. + * // `MRB_SYM()` is available via `mruby.h` (which includes `mruby/presym.h`). * // If the usage of `MRB_SYM()` is not desired, replace it with `mrb_intern_lit()`. * mrb_sym kw_names[] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) }; * mrb_value kw_values[kw_num]; @@ -1594,6 +1594,8 @@ MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...); #ifdef MRB_PRESYM_SCANNING # include +#else +# include #endif #if 0 diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index 43403fcad..abb9b71ac 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -109,7 +109,8 @@ module MRuby if build.kind_of?(MRuby::CrossBuild) return %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target) elsif build.kind_of?(MRuby::Build) - return ('A'..'Z').to_a.any? { |vol| Dir.exist?("#{vol}:") } + return ('A'..'Z').to_a.any? { |vol| Dir.exist?("#{vol}:") } || + ('a'..'z').to_a.any? { |vol| Dir.exist?("/#{vol}/") } end return false end diff --git a/mrbgems/hal-posix-socket/src/socket_hal.c b/mrbgems/hal-posix-socket/src/socket_hal.c index d333ee40a..1cc08c5af 100644 --- a/mrbgems/hal-posix-socket/src/socket_hal.c +++ b/mrbgems/hal-posix-socket/src/socket_hal.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "socket_hal.h" #include diff --git a/mrbgems/hal-win-socket/src/socket_hal.c b/mrbgems/hal-win-socket/src/socket_hal.c index 3acda0b5e..f052a0998 100644 --- a/mrbgems/hal-win-socket/src/socket_hal.c +++ b/mrbgems/hal-win-socket/src/socket_hal.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "socket_hal.h" #include #include diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index aa9467714..f31e58758 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c index a383f3aab..6376daaef 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "apiprint.h" static void diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 8c5fdb87b..511e0ce7d 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 1a7197eca..d5c159f3e 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -12,7 +12,6 @@ #include #include #include -#include #if defined(_WIN32) # include /* for setmode */ diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c index d5e3a0424..a5c9d6c01 100644 --- a/mrbgems/mruby-binding/src/binding.c +++ b/mrbgems/mruby-binding/src/binding.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/mrbgems/mruby-binding/test/binding.c b/mrbgems/mruby-binding/test/binding.c index efc982a75..e7dc5b08c 100644 --- a/mrbgems/mruby-binding/test/binding.c +++ b/mrbgems/mruby-binding/test/binding.c @@ -1,5 +1,4 @@ #include -#include static mrb_value binding_in_c(mrb_state *mrb, mrb_value self) diff --git a/mrbgems/mruby-catch/src/catch.c b/mrbgems/mruby-catch/src/catch.c index 29cacfc4d..4acbd822c 100644 --- a/mrbgems/mruby-catch/src/catch.c +++ b/mrbgems/mruby-catch/src/catch.c @@ -4,7 +4,6 @@ #include #include #include -#include /* Pre-defined symbols used by catch implementation */ MRB_PRESYM_DEFINE_VAR_AND_INITER(catch_syms, 3, MRB_SYM(Object), MRB_SYM(new), MRB_SYM(call)) diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index c95253872..13c9653a9 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -5,7 +5,6 @@ #include #include #include -#include /* * Get the name of a module/class. diff --git a/mrbgems/mruby-cmath/src/cmath.c b/mrbgems/mruby-cmath/src/cmath.c index b0c6675db..e89ec285a 100644 --- a/mrbgems/mruby-cmath/src/cmath.c +++ b/mrbgems/mruby-cmath/src/cmath.c @@ -10,7 +10,6 @@ */ #include -#include #ifdef MRB_NO_FLOAT # error CMath conflicts with 'MRB_NO_FLOAT' configuration diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 60f39ae8a..48cae6569 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -46,7 +46,6 @@ #include #include #include -#include #include "node.h" #include #include @@ -3176,8 +3175,12 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) { if (val) { int array_size = 0; + int first = 1; + int slimit = GEN_LIT_ARY_MAX; node *current = tree; + if (cursp() >= slimit) slimit = GEN_VAL_STACK_MAX; + /* Process each segment separated by NODE_LITERAL_DELIM */ while (current) { /* Find the segment boundaries without allocating */ @@ -3214,6 +3217,24 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) /* Only process non-empty segments */ if (!is_empty_segment) { + /* Flush accumulated elements when stack is full */ + if (cursp() >= slimit) { + if (array_size > 0) { + pop_n(array_size); + if (first) { + genop_2(s, OP_ARRAY, cursp(), array_size); + push(); + first = 0; + } + else { + pop(); + genop_2(s, OP_ARYPUSH, cursp(), array_size); + push(); + } + array_size = 0; + } + } + /* Temporarily terminate the segment by saving and clearing the cdr */ node *saved_cdr = NULL; if (segment_prev) { @@ -3244,8 +3265,14 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) } } - /* Generate the array from pushed elements */ - if (array_size > 0) { + /* Handle remaining elements */ + if (!first) { + if (array_size > 0) { + pop_n(array_size + 1); + genop_2(s, OP_ARYPUSH, cursp(), array_size); + } + } + else if (array_size > 0) { pop_n(array_size); genop_2(s, OP_ARRAY, cursp(), array_size); } @@ -3821,7 +3848,7 @@ codegen_array(codegen_scope *s, node *varnode, int val) node *elements = array->elements; int regular_elements = 0; int first = 1; - int slimit = GEN_VAL_STACK_MAX; + int slimit = GEN_LIT_ARY_MAX; if (!val) return; @@ -3831,7 +3858,7 @@ codegen_array(codegen_scope *s, node *varnode, int val) return; } - if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX; + if (cursp() >= slimit) slimit = GEN_VAL_STACK_MAX; /* Process each element using cons-list iteration, handling splats */ node *current = elements; @@ -4428,10 +4455,9 @@ codegen_case_match(codegen_scope *s, node *varnode, int val) current_in = current_in->cdr; } - /* No pattern matched - generate nil or error */ - if (val) { - genop_1(s, OP_LOADNIL, cursp()); - } + /* No pattern matched - raise NoMatchingPatternError */ + genop_1(s, OP_LOADFALSE, cursp()); + genop_1(s, OP_MATCHERR, cursp()); /* Dispatch all end jumps */ if (case_end_jumps != JMPLINK_START) { diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 74f482ade..fcec6c880 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -23,7 +23,6 @@ #include #include #include -#include #include "node.h" #define YYLEX_PARAM p diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c index 741c1d2e7..9da966203 100644 --- a/mrbgems/mruby-compiler/core/y.tab.c +++ b/mrbgems/mruby-compiler/core/y.tab.c @@ -85,7 +85,6 @@ #include #include #include -#include #include "node.h" #define YYLEX_PARAM p diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index 3caf3a72b..4eba1fe16 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #ifdef MRB_NO_FLOAT diff --git a/mrbgems/mruby-data/src/data.c b/mrbgems/mruby-data/src/data.c index 704c7d0c9..49fa2d6d1 100644 --- a/mrbgems/mruby-data/src/data.c +++ b/mrbgems/mruby-data/src/data.c @@ -13,7 +13,6 @@ #include #include #include -#include #define RDATA_LEN(st) RARRAY_LEN(st) #define RDATA_PTR(st) RARRAY_PTR(st) diff --git a/mrbgems/mruby-dir/src/dir.c b/mrbgems/mruby-dir/src/dir.c index 215f74381..eb12eb593 100644 --- a/mrbgems/mruby-dir/src/dir.c +++ b/mrbgems/mruby-dir/src/dir.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "dir_hal.h" #include diff --git a/mrbgems/mruby-encoding/src/encoding.c b/mrbgems/mruby-encoding/src/encoding.c index 4654e9fca..ac9d52fca 100644 --- a/mrbgems/mruby-encoding/src/encoding.c +++ b/mrbgems/mruby-encoding/src/encoding.c @@ -2,7 +2,6 @@ #include #include #include -#include #define ENC_ASCII_8BIT "ASCII-8BIT" #define ENC_BINARY "BINARY" diff --git a/mrbgems/mruby-errno/src/errno.c b/mrbgems/mruby-errno/src/errno.c index 37d82b954..881be2b13 100644 --- a/mrbgems/mruby-errno/src/errno.c +++ b/mrbgems/mruby-errno/src/errno.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 8845a534e..def92a691 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/mrbgems/mruby-exit/src/mruby_exit.c b/mrbgems/mruby-exit/src/mruby_exit.c index 7ba153a54..13da43201 100644 --- a/mrbgems/mruby-exit/src/mruby_exit.c +++ b/mrbgems/mruby-exit/src/mruby_exit.c @@ -2,7 +2,6 @@ #include #include #include -#include #ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 4fcb5cb56..c7655c4a7 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -6,7 +6,6 @@ #include #include #include -#include #define fiber_ptr(o) ((struct RFiber*)mrb_ptr(o)) diff --git a/mrbgems/mruby-hash-ext/src/hash_ext.c b/mrbgems/mruby-hash-ext/src/hash_ext.c index 2aac680d1..567f96366 100644 --- a/mrbgems/mruby-hash-ext/src/hash_ext.c +++ b/mrbgems/mruby-hash-ext/src/hash_ext.c @@ -9,7 +9,6 @@ #include #include #include -#include /* * call-seq: diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index f146233f3..096578b21 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "io_hal.h" #include diff --git a/mrbgems/mruby-io/src/file_test.c b/mrbgems/mruby-io/src/file_test.c index 6f1ad24f0..00d8b00a4 100644 --- a/mrbgems/mruby-io/src/file_test.c +++ b/mrbgems/mruby-io/src/file_test.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "io_hal.h" diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 6b161c936..58b3094a2 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "io_hal.h" #include diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index d9ea0e315..1ba93a33c 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -8,7 +8,6 @@ #include #include #include -#include /* * call-seq: diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index bf5ee9b5b..e746b7ce4 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -11,7 +11,6 @@ #endif #include -#include static void domain_error(mrb_state *mrb, const char *func) diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index 79b2ae46d..ecddd96cb 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -7,7 +7,6 @@ #include #include #include -#include #define MT_PROTECTED MRB_METHOD_PROTECTED_FL #define MT_NOPRIV (MRB_METHOD_PRIVATE_FL|MT_PROTECTED) diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index 69dcdedfc..ad0b63fcf 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -5,7 +5,6 @@ #include #include #include -#include // Defined by mruby-proc-ext on which mruby-method depends mrb_value mrb_proc_parameters(mrb_state *mrb, mrb_value proc); diff --git a/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 0a0ad174f..ac29bce99 100644 --- a/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -4,7 +4,6 @@ #include #include #include -#include #ifndef MRB_NO_FLOAT static mrb_value flo_remainder(mrb_state *mrb, mrb_value self); diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c index ba74c9174..7ffd8215f 100644 --- a/mrbgems/mruby-object-ext/src/object.c +++ b/mrbgems/mruby-object-ext/src/object.c @@ -4,7 +4,6 @@ #include #include #include -#include /* * call-seq: diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index 0d30e7f64..eeb23cc02 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -10,7 +10,6 @@ #include #include #include -#include struct os_count_struct { mrb_int total; diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 4383e2a7e..5f466924d 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/mrbgems/mruby-proc-binding/src/proc_binding.c b/mrbgems/mruby-proc-binding/src/proc_binding.c index 6838d223f..770237a68 100644 --- a/mrbgems/mruby-proc-binding/src/proc_binding.c +++ b/mrbgems/mruby-proc-binding/src/proc_binding.c @@ -1,5 +1,4 @@ #include -#include #include #include diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c index f9be0ef29..14c42a790 100644 --- a/mrbgems/mruby-proc-ext/src/proc.c +++ b/mrbgems/mruby-proc-ext/src/proc.c @@ -6,7 +6,6 @@ #include #include #include -#include /* * call-seq: diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index fadd77abb..b65170ae8 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index 1c0acc1c2..2a88e321a 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -2,7 +2,6 @@ #include #include #include -#include static mrb_bool r_less(mrb_state *mrb, mrb_value a, mrb_value b, mrb_bool excl) diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 951d6bfe3..4d265647f 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -2,7 +2,6 @@ #include #include #include -#include #ifndef MRB_NO_FLOAT #include diff --git a/mrbgems/mruby-set/src/set.c b/mrbgems/mruby-set/src/set.c index 21fc84d8e..82eec5b1b 100644 --- a/mrbgems/mruby-set/src/set.c +++ b/mrbgems/mruby-set/src/set.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/mrbgems/mruby-sleep/src/sleep.c b/mrbgems/mruby-sleep/src/sleep.c index 1183e10ec..292564de7 100644 --- a/mrbgems/mruby-sleep/src/sleep.c +++ b/mrbgems/mruby-sleep/src/sleep.c @@ -37,7 +37,6 @@ #endif #include -#include /* * call-seq: diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c index efbba6ed8..815bc2402 100644 --- a/mrbgems/mruby-socket/src/socket.c +++ b/mrbgems/mruby-socket/src/socket.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include "socket_hal.h" diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index bab3986b2..66f960d77 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/mrbgems/mruby-strftime/src/strftime.c b/mrbgems/mruby-strftime/src/strftime.c index 02a2d8675..94d659a1f 100644 --- a/mrbgems/mruby-strftime/src/strftime.c +++ b/mrbgems/mruby-strftime/src/strftime.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 451882c30..331aae7f1 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -5,7 +5,6 @@ #include #include #include -#include #define ENC_ASCII_8BIT "ASCII-8BIT" #define ENC_BINARY "BINARY" diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 3ba721ac5..4bd0129a0 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -14,7 +14,6 @@ #include #include #include -#include #define RSTRUCT_LEN(st) RARRAY_LEN(st) #define RSTRUCT_PTR(st) RARRAY_PTR(st) diff --git a/mrbgems/mruby-symbol-ext/src/symbol.c b/mrbgems/mruby-symbol-ext/src/symbol.c index 5825d0c62..ed4521ea0 100644 --- a/mrbgems/mruby-symbol-ext/src/symbol.c +++ b/mrbgems/mruby-symbol-ext/src/symbol.c @@ -3,7 +3,6 @@ #include #include #include -#include /* * call-seq: diff --git a/mrbgems/mruby-task/src/task.c b/mrbgems/mruby-task/src/task.c index 964969ab6..a8a627409 100644 --- a/mrbgems/mruby-task/src/task.c +++ b/mrbgems/mruby-task/src/task.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 458f91d23..291e3d11e 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -11,7 +11,6 @@ #include #include #include -#include #ifdef MRB_NO_STDIO #include diff --git a/src/array.c b/src/array.c index 27a5b0097..cf28c35d0 100644 --- a/src/array.c +++ b/src/array.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "value_array.h" #define ARY_DEFAULT_LEN 4 diff --git a/src/backtrace.c b/src/backtrace.c index c9d176785..ce4d9b140 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -15,7 +15,6 @@ #include #include #include -#include #define MAX_IREP_REFCNT UINT16_MAX #define UNKNOWN_LINENO -1 diff --git a/src/cdump.c b/src/cdump.c index 530a808fc..c453dfb97 100644 --- a/src/cdump.c +++ b/src/cdump.c @@ -456,7 +456,6 @@ mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE "#include \n" "#include \n" "#include \n" - "#include \n" "\n") < 0) { return MRB_DUMP_WRITE_FAULT; } diff --git a/src/class.c b/src/class.c index 1f95a08d6..cc6da75a3 100644 --- a/src/class.c +++ b/src/class.c @@ -17,7 +17,6 @@ #include #include #include -#include /* mrb_mt_tbl, union mrb_mt_ptr, mrb_mt_entry defined in internal.h */ #define MT_PROTECTED MRB_METHOD_PROTECTED_FL diff --git a/src/enum.c b/src/enum.c index c2720bf78..8ca563bc7 100644 --- a/src/enum.c +++ b/src/enum.c @@ -6,7 +6,6 @@ #include #include -#include /* internal method `__update_hash(oldhash, index, itemhash)` */ static mrb_value diff --git a/src/error.c b/src/error.c index 2115f3f5b..cce382537 100644 --- a/src/error.c +++ b/src/error.c @@ -16,7 +16,6 @@ #include #include #include -#include void mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) diff --git a/src/gc.c b/src/gc.c index 1206eaa6c..411cb6852 100644 --- a/src/gc.c +++ b/src/gc.c @@ -22,7 +22,6 @@ #include #include #include -#include #ifdef MRB_GC_STRESS #include diff --git a/src/hash.c b/src/hash.c index 084d98a6c..1dba928be 100644 --- a/src/hash.c +++ b/src/hash.c @@ -13,7 +13,6 @@ #include #include #include -#include /* diff --git a/src/kernel.c b/src/kernel.c index e7cd65834..315124cba 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -14,7 +14,6 @@ #include #include #include -#include /* * Checks if the method `mid` for object `obj` is implemented by diff --git a/src/numeric.c b/src/numeric.c index 5233a28b7..7c6b08469 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #ifndef MRB_NO_FLOAT diff --git a/src/numops.c b/src/numops.c index ff8adc2d6..9da0c3ae4 100644 --- a/src/numops.c +++ b/src/numops.c @@ -7,7 +7,6 @@ #include #include #include -#include MRB_API mrb_value mrb_num_add(mrb_state *mrb, mrb_value x, mrb_value y) diff --git a/src/object.c b/src/object.c index 6d2845103..da8ddb5e5 100644 --- a/src/object.c +++ b/src/object.c @@ -10,7 +10,6 @@ #include #include #include -#include /* * Checks if two mruby values, `v1` and `v2`, are identical. diff --git a/src/print.c b/src/print.c index 8d7bdcdfa..c54fa2049 100644 --- a/src/print.c +++ b/src/print.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #if defined(_WIN32) # include diff --git a/src/proc.c b/src/proc.c index 93cf46c5b..546d94907 100644 --- a/src/proc.c +++ b/src/proc.c @@ -12,7 +12,6 @@ #include #include #include -#include static const mrb_code call_iseq[] = { OP_CALL, diff --git a/src/range.c b/src/range.c index bd501ca8d..7a0e13890 100644 --- a/src/range.c +++ b/src/range.c @@ -11,7 +11,6 @@ #include #include #include -#include #define RANGE_INITIALIZED_FLAG 1 #define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_FLAG) diff --git a/src/string.c b/src/string.c index def95e535..d490ec310 100644 --- a/src/string.c +++ b/src/string.c @@ -16,7 +16,6 @@ #include #include #include -#include #include typedef struct mrb_shared_string { diff --git a/src/symbol.c b/src/symbol.c index 01c7cb6ec..f24987e17 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -10,7 +10,6 @@ #include #include #include -#include #ifndef MRB_PRESYM_SCANNING /* const uint16_t presym_length_table[] */ diff --git a/src/variable.c b/src/variable.c index a40353ce4..45e4e02ea 100644 --- a/src/variable.c +++ b/src/variable.c @@ -11,7 +11,6 @@ #include #include #include -#include /* Instance variable table structure */ typedef struct iv_tbl { diff --git a/src/vm.c b/src/vm.c index 0ff62efe1..f898287d8 100644 --- a/src/vm.c +++ b/src/vm.c @@ -20,7 +20,6 @@ #include #include #include -#include #ifdef MRB_NO_STDIO #if defined(__cplusplus) @@ -708,7 +707,9 @@ prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, m } else { mrb_assert(ci->nk == 15); - argv[1] = argv[ci->n]; + if (ci->n != CALL_MAXARGS) { + argv[1] = argv[ci->n]; /* keyword arguments */ + } argv[2] = blk; } argv[0] = args; /* must be replaced after saving argv[0] as it may be a keyword argument */ diff --git a/tasks/presym.rake b/tasks/presym.rake index e61915e07..619957e99 100644 --- a/tasks/presym.rake +++ b/tasks/presym.rake @@ -7,8 +7,6 @@ all_prerequisites = ->(task_name, prereqs) do end MRuby.each_target do |build| - gensym_task = task(:gensym) - presym = build.presym include_dir = "#{build.build_dir}/include" @@ -34,12 +32,12 @@ MRuby.each_target do |build| file presym.list_path => ppps do presyms = presym.scan(ppps) current_presyms = presym.read_list if File.exist?(presym.list_path) - update = presyms != current_presyms - presym.write_list(presyms) if update - mkdir_p presym.header_dir - %w[id table].each do |type| - next if !update && File.exist?(presym.send("#{type}_header_path")) - presym.send("write_#{type}_header", presyms) + if presyms != current_presyms + mkdir_p presym.header_dir + %w[id table].each do |type| + presym.send("write_#{type}_header", presyms) + end + presym.write_list(presyms) end end @@ -55,5 +53,5 @@ MRuby.each_target do |build| file prereq => presym.list_path end - gensym_task.enhance([presym.list_path]) + task gensym: presym.list_path end diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 42a6d4198..a02ca1d8a 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -1246,12 +1246,13 @@ assert('pattern matching - NoMatchingPatternError') do assert_true e.message.is_a?(String) end - # case/in without else returns nil (no match) - result = case 5 - in 1 then :one - in 2 then :two + # case/in without else raises NoMatchingPatternError + assert_raise(NoMatchingPatternError) do + case 5 + in 1 then :one + in 2 then :two + end end - assert_nil result end assert('pattern matching - complex patterns') do