mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bec339230 | |||
| 242a7f14e0 | |||
| f13db72d26 | |||
| b82065aa92 | |||
| 11679e3f3a | |||
| 82d3b3d11b | |||
| 2cbfc2f350 | |||
| 6db4a58fbd | |||
| 96cfde3488 | |||
| 2e48070ab6 | |||
| d823045af4 | |||
| c9ab1e601d | |||
| beef5d37ad | |||
| 15f597e835 | |||
| 84b0ba3f8d | |||
| 7d3bc5c3d7 | |||
| f71d389649 | |||
| eaadc5e79f | |||
| c627e3b2ab | |||
| 9424e4d4cf | |||
| 64d3f4c730 |
@@ -6,7 +6,7 @@
|
||||
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "mruby"
|
||||
PROJECT_NUMBER = 3.0.0
|
||||
PROJECT_NUMBER = 3.1.0
|
||||
|
||||
PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ of the Ministry of Economy, Trade and Industry of Japan.
|
||||
|
||||
## How to get mruby
|
||||
|
||||
The release candidate version 3.1.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.1.0-rc.zip](https://github.com/mruby/mruby/archive/3.1.0-rc.zip)
|
||||
The stable version 3.1.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.1.0.zip](https://github.com/mruby/mruby/archive/3.1.0.zip)
|
||||
|
||||
The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master)
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option:
|
||||
|
||||
```bash
|
||||
$ mrdb --version
|
||||
mruby 3.0.0 (2021-03-05)
|
||||
mruby 3.1.0 (2022-05-12)
|
||||
```
|
||||
|
||||
## 2.2 Basic Operation
|
||||
|
||||
+8
-8
@@ -30,7 +30,7 @@ end
|
||||
|
||||
`ZeroDivisionError` is raised.
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
`RuntimeError` is raised instead of `ZeroDivisionError`. To re-raise the exception, you have to do:
|
||||
|
||||
@@ -66,7 +66,7 @@ p Liste.new "foobar"
|
||||
|
||||
` [] `
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
`ArgumentError` is raised.
|
||||
|
||||
@@ -96,7 +96,7 @@ false
|
||||
true
|
||||
```
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
```
|
||||
true
|
||||
@@ -133,7 +133,7 @@ p 'ok'
|
||||
ok
|
||||
```
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
```
|
||||
test.rb:8: undefined method 'test_func' (NoMethodError)
|
||||
@@ -155,7 +155,7 @@ defined?(Foo)
|
||||
nil
|
||||
```
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
`NameError` is raised.
|
||||
|
||||
@@ -172,7 +172,7 @@ alias $a $__a__
|
||||
|
||||
` nil `
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
Syntax error
|
||||
|
||||
@@ -194,7 +194,7 @@ end
|
||||
`ArgumentError` is raised.
|
||||
The re-defined `+` operator does not accept any arguments.
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
` 'ab' `
|
||||
Behavior of the operator wasn't changed.
|
||||
@@ -210,7 +210,7 @@ $ ruby -e 'puts Proc.new {}.binding'
|
||||
#<Binding:0x00000e9deabb9950>
|
||||
```
|
||||
|
||||
#### mruby [3.0.0 (2021-03-05)]
|
||||
#### mruby [3.1.0 (2022-05-12)]
|
||||
|
||||
```
|
||||
$ ./bin/mruby -e 'puts Proc.new {}.binding'
|
||||
|
||||
+149
-42
@@ -1,48 +1,91 @@
|
||||
# User visible changes in `mruby3.1` from `mruby3.0`
|
||||
|
||||
# Build System
|
||||
# New Features
|
||||
|
||||
## `build_config` directory
|
||||
## Core Language Features
|
||||
|
||||
Several configurations for new platforms are added:
|
||||
### Keyword Arguments
|
||||
|
||||
* `cross-mingw-winetest.rb`
|
||||
* `cross-mingw.rb`
|
||||
* `nintendo_switch.rb`
|
||||
* `serenity.rb`
|
||||
CRuby3.0 compatible keyword arguments are introduced.
|
||||
Keyword arguments are basically separated from ordinal arguments.
|
||||
|
||||
Some new configurations for added for convenience.
|
||||
### Other Language Enhancement
|
||||
|
||||
* `minimal`: minimal configuration
|
||||
* `host-f32`: compiles with `mrb_float` as 32 bit `float`
|
||||
* `host-nofloat`: compiles with no float configuration
|
||||
- Implement endless-def [Ruby:Feature#16746](https://bugs.ruby-lang.org/issues/16746)
|
||||
- Replace `R-assignment` by `single-line pattern matching` [Ruby:Feature#15921](https://bugs.ruby-lang.org/issues/15921)
|
||||
- Support squiggly heredocs. [#5246](https://github.com/mruby/mruby/pull/5246)
|
||||
- Hash value omission [Ruby:Feature#14579](https://bugs.ruby-lang.org/issues/14579)
|
||||
|
||||
And `android_arm64-v8a.rb` was renamed to `android_arm64_v8a.rb` for consistency.
|
||||
|
||||
# Configuration Options Changed
|
||||
## Configuration Options Changed
|
||||
|
||||
Some configuration macros are available:
|
||||
|
||||
* `MRB_WORDBOX_NO_FLOAT_TRUNCATE`: by default, float values are packed in the word if possible, but define this macro to allocate float values in the heap.
|
||||
* `MRB_USE_RO_DATA_P_ETEXT`: define this macro if `_etext` is available on your platform.
|
||||
* `MRB_NO_DEFAULT_RO_DATA_P`: define this macro to avoid using predefined `mrb_ro_data_p()` function
|
||||
- `MRB_WORDBOX_NO_FLOAT_TRUNCATE`: by default, float values are packed in the word if possible, but define this macro to allocate float values in the heap.
|
||||
- `MRB_USE_RO_DATA_P_ETEXT`: define this macro if `_etext` is available on your platform.
|
||||
- `MRB_NO_DEFAULT_RO_DATA_P`: define this macro to avoid using predefined `mrb_ro_data_p()` function
|
||||
|
||||
# Language Changes
|
||||
---
|
||||
|
||||
## Keyword Arguments
|
||||
# Updated Features
|
||||
|
||||
CRuby3.0 compatible keyword arguments are introduced.
|
||||
Keyword arguments are basically separated from ordinal arguments
|
||||
## New build configurations
|
||||
|
||||
## New Methods
|
||||
We have added several new build configurations in the `build_config` directory.
|
||||
|
||||
* `Array#product`
|
||||
* `Array#repeated_combination`
|
||||
* `Array#repeated_permutation`
|
||||
* `Random.bytes`
|
||||
* `Random#bytes`
|
||||
- `cross-mingw-winetest.rb`
|
||||
- `cross-mingw.rb`
|
||||
- `nintendo_switch.rb`
|
||||
- `serenity.rb`
|
||||
- `minimal`: minimal configuration
|
||||
- `host-f32`: compiles with `mrb_float` as 32 bit `float`
|
||||
- `host-nofloat`: compiles with no float configuration
|
||||
- `android_arm64_v8a.rb`: renamed from `android_arm64-v8a.rb`
|
||||
|
||||
# Internal Changes
|
||||
## Core Libraries
|
||||
|
||||
### New Methods
|
||||
|
||||
- `Array#product`
|
||||
- `Array#repeated_combination`
|
||||
- `Array#repeated_permutation`
|
||||
- `Kernel#__ENCODING__`
|
||||
- `Random.bytes`
|
||||
- `Random#bytes`
|
||||
- `String#center`
|
||||
|
||||
### New Gem Enhancement
|
||||
|
||||
- `mrbgems/mruby-pack` now supports `M` directive (Q encoding)
|
||||
- `mrbgems/mruby-pack` now supports `X` directive (back-up by bytes)
|
||||
- `mrbgems/mruby-pack` now supports `@` directive (absolute position)
|
||||
- `mrbgems/mruby-pack` now supports `w` directive (BER compression)
|
||||
|
||||
## Tools
|
||||
|
||||
- `mruby-config` now supports `--cc` and `--ld` options.
|
||||
- Remove `OP_` prefix from `mruby -v` code dump output.
|
||||
- Prohibit use of `OP_EXT{1,2,3}` by `mrbc` with `--no-ext-ops` option.
|
||||
|
||||
## Features for mruby Developer
|
||||
|
||||
- Add new specifier `c` to `mrb_get_args()` for receive Class/Module.
|
||||
|
||||
---
|
||||
|
||||
# Breaking Changes
|
||||
|
||||
## Incompatibly Changed Methods
|
||||
|
||||
- `Kernel#printf` (`mruby-sprintf`) Format specifiers `%a` and `%A` are removed.
|
||||
- `Kernel#puts` (`mruby-print`) Now expand Array arguments.
|
||||
|
||||
## mruby VM and bytecode
|
||||
|
||||
Due to improvements in the binary format, mruby binaries are no longer backward compatible.
|
||||
To run the mruby binaries on mruby 3.1, recompile with the mruby 3.1 `mrbc`.
|
||||
|
||||
- Upgrade mruby VM version `RITE_VM_VER` to `0300` (means mruby 3.0 or after).
|
||||
- Upgrade mruby binary version `RITE_BINARY_FORMAT_VER` to `0300`.
|
||||
|
||||
## Reintroduced Instructions
|
||||
|
||||
@@ -53,18 +96,18 @@ Keyword arguments are basically separated from ordinal arguments
|
||||
|
||||
`mruby3.1` removed following instructions.
|
||||
|
||||
* `OP_LOADL16`
|
||||
* `OP_LOADSYM16`
|
||||
* `OP_STRING16`
|
||||
* `OP_LAMBDA16`
|
||||
* `OP_BLOCK16`
|
||||
* `OP_METHOD16`
|
||||
* `OP_EXEC16`
|
||||
- `OP_LOADL16`
|
||||
- `OP_LOADSYM16`
|
||||
- `OP_STRING16`
|
||||
- `OP_LAMBDA16`
|
||||
- `OP_BLOCK16`
|
||||
- `OP_METHOD16`
|
||||
- `OP_EXEC16`
|
||||
|
||||
Those instructions are no longer needed by reintroduction of extension instructions.
|
||||
|
||||
* `OP_SENDV`
|
||||
* `OP_SENDVB`
|
||||
- `OP_SENDV`
|
||||
- `OP_SENDVB`
|
||||
|
||||
Those instructions for method calls with variable number of arguments are no longer needed. They are covered by `OP_SEND` instruction with `n=15`.
|
||||
|
||||
@@ -72,10 +115,11 @@ Those instructions for method calls with variable number of arguments are no lon
|
||||
|
||||
`mruby3.1` introduces following new instructions.
|
||||
|
||||
* `OP_GETIDX`: takes 2 operands `a[b]`
|
||||
* `OP_SETIDX`: takes 3 operands `a[b]=c`
|
||||
* `OP_SSEND`: takes 3 operands `a=self.b(c...)`; see `OP_SEND`
|
||||
* `OP_SSENDB`: takes 3 operands `a=self.b(c...){...}`; see `OP_SEND`
|
||||
- `OP_GETIDX`: takes 1 operands `R[a][a+1]`
|
||||
- `OP_SETIDX`: takes 1 operands `R[a][a+1]=R[a+2]`
|
||||
- `OP_SSEND`: takes 3 operands `a=self.b(c...)`; see `OP_SEND`
|
||||
- `OP_SSENDB`: takes 3 operands `a=self.b(c...){...}`; see `OP_SEND`
|
||||
- `OP_SYMBOL`: takes 2 operands `R[a] = intern(Pool[b])`
|
||||
|
||||
### `OP_GETIDX` and `OP_SETIDX`
|
||||
|
||||
@@ -85,6 +129,10 @@ Execute `obj[int]` and `obj[int] = value` respectively, where `obj` is `string|a
|
||||
|
||||
They are similar to `OP_SEND` and `OP_SENDB` respectively. They initialize the `R[a]` by `self` first so that we can skip one `OP_LOADSELF` instruction for each call.
|
||||
|
||||
### `OP_SYMBOL`
|
||||
|
||||
Extracts the character string placed in the pool as a symbol.
|
||||
|
||||
## Changed Instructions
|
||||
|
||||
### `OP_SEND` and `OP_SENDB`
|
||||
@@ -114,7 +162,7 @@ If the size of `mrb_float` and `mrb_int` are same, the last 2 bits in the `mrb_f
|
||||
|
||||
Previous NaN boxing packs values in NaN representation, but pointer retrievals are far more frequent than floating point number references. So we add constant offset to NaN representation to clear higher bits of pointer representation. This representation is called "Favor Pointer" NaN Boxing.
|
||||
|
||||
Also, previous NaN boxing limit the size of `mrb_int` to 4 bytes (32 bits) to fit in NaN values. Now we allocates integer values in the heap, if the value does not fit in the 32 bit range, just like we did in Word Boxing.
|
||||
Also, previous NaN boxing limit the size of `mrb_int` to 4 bytes (32 bits) to fit in NaN values. Now we allocate integer values in the heap, if the value does not fit in the 32 bit range, just like we did in Word Boxing.
|
||||
|
||||
## Constant Folding
|
||||
|
||||
@@ -146,3 +194,62 @@ GETIV R1 :@foo
|
||||
## `String#hash` now use `FNV1a` algorithm
|
||||
|
||||
For better and faster hash values.
|
||||
|
||||
---
|
||||
|
||||
# Major bug fixes
|
||||
|
||||
- Fix infinite recursive call bugs in integer division [98799aa6](https://github.com/mruby/mruby/commit/98799aa6)
|
||||
- Fix to raise TypeError with super inside instance_eval / class_eval [#5476](https://github.com/mruby/mruby/pull/5476)
|
||||
- Fix to call `method_added` hooks on method definitions; [#2339](https://github.com/mruby/mruby/pull/2339)
|
||||
- Fix a potential buffer overflow in `time_zonename` [26340a88](https://github.com/mruby/mruby/commit/26340a88)
|
||||
- Fix `Module.instance_eval` bug [#5528](https://github.com/mruby/mruby/pull/5528)
|
||||
- Fix fix `M` packing bug [bfe2bd49](https://github.com/mruby/mruby/commit/bfe2bd49)
|
||||
- Fix a bug regarding attribute assignment with kargs [de2b4bd0](https://github.com/mruby/mruby/commit/de2b4bd0)
|
||||
- Fix SIGSEGV with mrbgems/mruby-method [#5580](https://github.com/mruby/mruby/pull/5580)
|
||||
- Fix print error before cleanup in `codegen_error()` [#5603](https://github.com/mruby/mruby/pull/5603)
|
||||
- Fix a bug in unpacking BER [#5611](https://github.com/mruby/mruby/pull/5611)
|
||||
- Fix a bug with numbered parameters as arguments [#5605](https://github.com/mruby/mruby/pull/5605)
|
||||
- Fix `mrb_ary_shift_m` initialization bug [27d1e013](https://github.com/mruby/mruby/commit/27d1e013)
|
||||
- Fix keyword argument with `super` [#5628](https://github.com/mruby/mruby/pull/5628)
|
||||
- Fix a bug with numbered parameters on toplevel [7e7f1b2f](https://github.com/mruby/mruby/commit/7e7f1b2f)
|
||||
- Fix keyword argument bug [#5632](https://github.com/mruby/mruby/issues/5632)
|
||||
- Fix multiple assignments in parameters [#5647](https://github.com/mruby/mruby/issues/5647)
|
||||
- Fix keyword parameters not passing through super [#5660](https://github.com/mruby/mruby/issues/5660)
|
||||
- Fix infinite loop from unclosed here-doc [#5676](https://github.com/mruby/mruby/issues/5676)
|
||||
- Fix negative integer division bug [#5678](https://github.com/mruby/mruby/issues/5678)
|
||||
|
||||
# CVEs
|
||||
|
||||
## Fixed CVEs
|
||||
|
||||
Following CVEs are fixed in this release.
|
||||
|
||||
- [CVE-2021-4110](https://nvd.nist.gov/vuln/detail/CVE-2021-4110)
|
||||
- [CVE-2021-4188](https://nvd.nist.gov/vuln/detail/CVE-2021-4188)
|
||||
- [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080)
|
||||
- [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240)
|
||||
- [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326)
|
||||
- [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481)
|
||||
- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631)
|
||||
- [CVE-2022-0632](https://nvd.nist.gov/vuln/detail/CVE-2022-0632)
|
||||
- [CVE-2022-0890](https://nvd.nist.gov/vuln/detail/CVE-2022-0890)
|
||||
- [CVE-2022-1071](https://nvd.nist.gov/vuln/detail/CVE-2022-1071)
|
||||
- [CVE-2022-1106](https://nvd.nist.gov/vuln/detail/CVE-2022-1106)
|
||||
- [CVE-2022-1201](https://nvd.nist.gov/vuln/detail/CVE-2022-1201)
|
||||
- [CVE-2022-1427](https://nvd.nist.gov/vuln/detail/CVE-2022-1427)
|
||||
|
||||
## Unaffected CVEs
|
||||
|
||||
Following CVEs do not cause problems in this release. They are fixed in the later release.
|
||||
|
||||
- [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481)
|
||||
- [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525)
|
||||
- [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570)
|
||||
- [CVE-2022-0614](https://nvd.nist.gov/vuln/detail/CVE-2022-0614)
|
||||
- [CVE-2022-0623](https://nvd.nist.gov/vuln/detail/CVE-2022-0623)
|
||||
- [CVE-2022-0630](https://nvd.nist.gov/vuln/detail/CVE-2022-0630)
|
||||
- [CVE-2022-0717](https://nvd.nist.gov/vuln/detail/CVE-2022-0817)
|
||||
- [CVE-2022-1212](https://nvd.nist.gov/vuln/detail/CVE-2022-1212)
|
||||
- [CVE-2022-1276](https://nvd.nist.gov/vuln/detail/CVE-2022-1276)
|
||||
- [CVE-2022-1286](https://nvd.nist.gov/vuln/detail/CVE-2022-1286)
|
||||
|
||||
@@ -57,7 +57,7 @@ MRB_BEGIN_DECL
|
||||
/*
|
||||
* Patch level string. (optional)
|
||||
*/
|
||||
#define MRUBY_PATCHLEVEL_STR "RC"
|
||||
#define MRUBY_PATCHLEVEL_STR ""
|
||||
|
||||
#ifndef MRUBY_PATCHLEVEL_STR
|
||||
# if MRUBY_PATCHLEVEL < 0
|
||||
@@ -85,12 +85,12 @@ MRB_BEGIN_DECL
|
||||
/*
|
||||
* Release month.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MONTH 1
|
||||
#define MRUBY_RELEASE_MONTH 5
|
||||
|
||||
/*
|
||||
* Release day.
|
||||
*/
|
||||
#define MRUBY_RELEASE_DAY 7
|
||||
#define MRUBY_RELEASE_DAY 12
|
||||
|
||||
/*
|
||||
* Release date as a string.
|
||||
|
||||
@@ -839,7 +839,7 @@ gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst)
|
||||
}
|
||||
else { /* OP_DIV */
|
||||
if (n0 == MRB_INT_MIN && n == -1) goto normal;
|
||||
n = n0 / n;
|
||||
n = mrb_div_int(s->mrb, n0, n);
|
||||
}
|
||||
s->pc = addr_pc(s, data0.addr);
|
||||
gen_int(s, dst, n);
|
||||
@@ -1603,7 +1603,7 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit)
|
||||
|
||||
while (tree) {
|
||||
if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) {
|
||||
if (len > 0) {
|
||||
if (val && len > 0) {
|
||||
pop_n(len*2);
|
||||
if (!update) {
|
||||
genop_2(s, OP_HASH, cursp(), len);
|
||||
@@ -1615,7 +1615,7 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit)
|
||||
push();
|
||||
}
|
||||
codegen(s, tree->car->cdr, val);
|
||||
if (len > 0 || update) {
|
||||
if (val && (len > 0 || update)) {
|
||||
pop(); pop();
|
||||
genop_1(s, OP_HASHCAT, cursp());
|
||||
push();
|
||||
@@ -1644,14 +1644,13 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit)
|
||||
}
|
||||
}
|
||||
if (update) {
|
||||
if (len > 0) {
|
||||
if (val && len > 0) {
|
||||
pop_n(len*2+1);
|
||||
genop_2(s, OP_HASHADD, cursp(), len);
|
||||
push();
|
||||
}
|
||||
return -1; /* variable length */
|
||||
}
|
||||
if (update) return -1;
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -2851,7 +2850,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
}
|
||||
/* keyword arguments */
|
||||
if (s2 && (s2->ainfo & 0x1) && tree->cdr->car) {
|
||||
if (tree->cdr->car) {
|
||||
nk = gen_hash(s, tree->cdr->car->cdr, VAL, 14);
|
||||
if (nk < 0) {st++; nk = 15;}
|
||||
else st += nk*2;
|
||||
@@ -2861,19 +2860,20 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (tree->cdr->cdr) {
|
||||
codegen(s, tree->cdr->cdr, VAL);
|
||||
}
|
||||
else if (!s2) {/* super at top-level */
|
||||
push(); /* no need to push block */
|
||||
}
|
||||
else if (s2) gen_blkmove(s, s2->ainfo, lv);
|
||||
else {
|
||||
gen_blkmove(s, s2->ainfo, lv);
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
push();
|
||||
}
|
||||
st++;
|
||||
}
|
||||
else {
|
||||
if (!s2) push();
|
||||
else gen_blkmove(s, s2->ainfo, lv);
|
||||
st++;
|
||||
if (s2) gen_blkmove(s, s2->ainfo, lv);
|
||||
else {
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
push();
|
||||
}
|
||||
}
|
||||
st++;
|
||||
pop_n(st+1);
|
||||
genop_2(s, OP_SUPER, cursp(), n);
|
||||
if (val) push();
|
||||
@@ -3125,6 +3125,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
codegen_error(s, "no anonymous block argument");
|
||||
}
|
||||
gen_move(s, cursp(), idx, val);
|
||||
if (val) push();
|
||||
}
|
||||
else {
|
||||
codegen(s, tree, val);
|
||||
|
||||
@@ -2962,6 +2962,7 @@ f_margs : f_arg
|
||||
}
|
||||
| f_arg ',' tSTAR
|
||||
{
|
||||
local_add_f(p, intern_op(mul));
|
||||
$$ = list3($1, nint(-1), 0);
|
||||
}
|
||||
| f_arg ',' tSTAR ',' f_arg
|
||||
@@ -2978,11 +2979,16 @@ f_margs : f_arg
|
||||
}
|
||||
| tSTAR
|
||||
{
|
||||
local_add_f(p, intern_op(mul));
|
||||
$$ = list3(0, nint(-1), 0);
|
||||
}
|
||||
| tSTAR ',' f_arg
|
||||
| tSTAR ','
|
||||
{
|
||||
$$ = list3(0, nint(-1), $3);
|
||||
local_add_f(p, intern_op(mul));
|
||||
}
|
||||
f_arg
|
||||
{
|
||||
$$ = list3(0, nint(-1), $4);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -3864,6 +3870,7 @@ f_arg_item : f_norm_arg
|
||||
{
|
||||
$$ = new_masgn_param(p, $3, p->locals->car);
|
||||
local_resume(p, $<nd>2);
|
||||
local_add_f(p, 0);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -4849,7 +4856,7 @@ parse_string(parser_state *p)
|
||||
--len;
|
||||
}
|
||||
}
|
||||
if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
|
||||
if (hinf->term_len > 0 && len-1 == hinf->term_len && strncmp(s, hinf->term, len-1) == 0) {
|
||||
heredoc_remove_indent(p, hinf);
|
||||
return tHEREDOC_END;
|
||||
}
|
||||
|
||||
+1621
-1610
File diff suppressed because it is too large
Load Diff
@@ -208,15 +208,22 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
|
||||
if (!c->ci->proc) {
|
||||
mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)");
|
||||
}
|
||||
mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */
|
||||
b = c->stbase+1;
|
||||
e = b + len;
|
||||
while (b<e) {
|
||||
*b++ = *a++;
|
||||
}
|
||||
if (vmexec) {
|
||||
c->ci--; /* pop dummy callinfo */
|
||||
}
|
||||
if (len >= 15) {
|
||||
mrb_stack_extend(mrb, 3); /* for receiver, args and (optional) block */
|
||||
c->stbase[1] = mrb_ary_new_from_values(mrb, len, a);
|
||||
len = 15;
|
||||
}
|
||||
else {
|
||||
mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */
|
||||
b = c->stbase+1;
|
||||
e = b + len;
|
||||
while (b<e) {
|
||||
*b++ = *a++;
|
||||
}
|
||||
}
|
||||
c->cibase->n = len;
|
||||
value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0];
|
||||
}
|
||||
|
||||
@@ -357,6 +357,7 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
|
||||
{
|
||||
struct RClass *sc, *c;
|
||||
|
||||
mrb_assert(o->c);
|
||||
if (o->c->tt == MRB_TT_SCLASS) return;
|
||||
sc = MRB_OBJ_ALLOC(mrb, MRB_TT_SCLASS, mrb->class_class);
|
||||
sc->flags |= MRB_FL_CLASS_IS_INHERITED;
|
||||
@@ -1682,6 +1683,7 @@ mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v)
|
||||
break;
|
||||
}
|
||||
obj = mrb_basic_ptr(v);
|
||||
if (obj->c == NULL) return NULL;
|
||||
prepare_singleton_class(mrb, obj);
|
||||
return obj->c;
|
||||
}
|
||||
|
||||
+62
-29
@@ -59,7 +59,7 @@ str_to_double(mrb_state *mrb, const char *p)
|
||||
#endif
|
||||
|
||||
static mrb_bool
|
||||
read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags, mrb_irep **irepp)
|
||||
read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_t *len, uint8_t flags, mrb_irep **irepp)
|
||||
{
|
||||
int i;
|
||||
const uint8_t *src = bin;
|
||||
@@ -102,6 +102,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (src + data_len > end) return FALSE;
|
||||
if ((flags & FLAG_SRC_MALLOC) == 0) {
|
||||
irep->iseq = (mrb_code*)src;
|
||||
irep->flags |= MRB_ISEQ_NO_FREE;
|
||||
@@ -117,6 +118,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
/* POOL BLOCK */
|
||||
plen = bin_to_uint16(src); /* number of pool */
|
||||
src += sizeof(uint16_t);
|
||||
if (src > end) return FALSE;
|
||||
if (plen > 0) {
|
||||
if (SIZE_ERROR_MUL(plen, sizeof(mrb_value))) {
|
||||
return FALSE;
|
||||
@@ -130,6 +132,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
switch (tt) { /* pool data */
|
||||
case IREP_TT_INT32:
|
||||
{
|
||||
if (src + sizeof(uint32_t) > end) return FALSE;
|
||||
mrb_int v = (int32_t)bin_to_uint32(src);
|
||||
src += sizeof(uint32_t);
|
||||
#ifdef MRB_64BIT
|
||||
@@ -144,6 +147,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
case IREP_TT_INT64:
|
||||
#ifdef MRB_INT64
|
||||
{
|
||||
if (src + sizeof(uint32_t)*2 > end) return FALSE;
|
||||
uint64_t i64 = bin_to_uint32(src);
|
||||
src += sizeof(uint32_t);
|
||||
i64 <<= 32;
|
||||
@@ -160,6 +164,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
case IREP_TT_BIGINT:
|
||||
pool_data_len = bin_to_uint8(src); /* pool data length */
|
||||
src += sizeof(uint8_t);
|
||||
if (src + pool_data_len > end) return FALSE;
|
||||
{
|
||||
char *p;
|
||||
pool[i].tt = IREP_TT_BIGINT;
|
||||
@@ -172,6 +177,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
|
||||
case IREP_TT_FLOAT:
|
||||
#ifndef MRB_NO_FLOAT
|
||||
if (src + sizeof(double) > end) return FALSE;
|
||||
pool[i].tt = tt;
|
||||
pool[i].u.f = str_to_double(mrb, (const char*)src);
|
||||
src += sizeof(double);
|
||||
@@ -183,6 +189,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
case IREP_TT_STR:
|
||||
pool_data_len = bin_to_uint16(src); /* pool data length */
|
||||
src += sizeof(uint16_t);
|
||||
if (src + pool_data_len > end) return FALSE;
|
||||
if (st) {
|
||||
pool[i].tt = (pool_data_len<<2) | IREP_TT_SSTR;
|
||||
pool[i].u.str = (const char*)src;
|
||||
@@ -208,6 +215,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
/* SYMS BLOCK */
|
||||
irep->slen = bin_to_uint16(src); /* syms length */
|
||||
src += sizeof(uint16_t);
|
||||
if (src > end) return FALSE;
|
||||
if (irep->slen > 0) {
|
||||
if (SIZE_ERROR_MUL(irep->slen, sizeof(mrb_sym))) {
|
||||
return FALSE;
|
||||
@@ -223,6 +231,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
continue;
|
||||
}
|
||||
|
||||
if (src + snl > end) return FALSE;
|
||||
if (flags & FLAG_SRC_MALLOC) {
|
||||
syms[i] = mrb_intern(mrb, (char *)src, snl);
|
||||
}
|
||||
@@ -242,10 +251,10 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags, mrb_irep **irepp)
|
||||
read_irep_record(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_t *len, uint8_t flags, mrb_irep **irepp)
|
||||
{
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
mrb_bool readsuccess = read_irep_record_1(mrb, bin, len, flags, irepp);
|
||||
mrb_bool readsuccess = read_irep_record_1(mrb, bin, end, len, flags, irepp);
|
||||
mrb_irep **reps;
|
||||
int i;
|
||||
|
||||
@@ -261,7 +270,7 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags,
|
||||
for (i=0; i<(*irepp)->rlen; i++) {
|
||||
size_t rlen;
|
||||
|
||||
readsuccess = read_irep_record(mrb, bin, &rlen, flags, &reps[i]);
|
||||
readsuccess = read_irep_record(mrb, bin, end, &rlen, flags, &reps[i]);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
if (!readsuccess) {
|
||||
return FALSE;
|
||||
@@ -274,10 +283,9 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags,
|
||||
}
|
||||
|
||||
static mrb_irep*
|
||||
read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags, struct RProc **proc)
|
||||
read_section_irep(mrb_state *mrb, const uint8_t *bin, size_t size, uint8_t flags, struct RProc **proc)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (size < sizeof(struct rite_section_irep_header)) return NULL;
|
||||
/*
|
||||
* This proc object keeps all the data in progress to avoid memory leaks
|
||||
* if something goes wrong while reading irep.
|
||||
@@ -285,8 +293,9 @@ read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags, struct RPro
|
||||
*proc = mrb_proc_new(mrb, NULL);
|
||||
|
||||
mrb_irep **irepp = (mrb_irep**)&(*proc)->body.irep;
|
||||
size_t len;
|
||||
bin += sizeof(struct rite_section_irep_header);
|
||||
if (read_irep_record(mrb, bin, &len, flags, irepp)) {
|
||||
if (read_irep_record(mrb, bin, bin+size, &len, flags, irepp)) {
|
||||
return *irepp;
|
||||
}
|
||||
else {
|
||||
@@ -295,7 +304,7 @@ read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags, struct RPro
|
||||
}
|
||||
|
||||
static int
|
||||
read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len)
|
||||
read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len)
|
||||
{
|
||||
const uint8_t *bin = start;
|
||||
ptrdiff_t diff;
|
||||
@@ -313,13 +322,15 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
|
||||
bin += sizeof(uint32_t);
|
||||
|
||||
debug->flen = bin_to_uint16(bin);
|
||||
debug->files = (mrb_irep_debug_info_file**)mrb_calloc(mrb, irep->debug_info->flen, sizeof(mrb_irep_debug_info*));
|
||||
bin += sizeof(uint16_t);
|
||||
if (bin > end) return MRB_DUMP_GENERAL_FAILURE;
|
||||
debug->files = (mrb_irep_debug_info_file**)mrb_calloc(mrb, irep->debug_info->flen, sizeof(mrb_irep_debug_info*));
|
||||
|
||||
for (f_idx = 0; f_idx < debug->flen; ++f_idx) {
|
||||
mrb_irep_debug_info_file *file;
|
||||
uint16_t filename_idx;
|
||||
|
||||
if (bin > end) return MRB_DUMP_GENERAL_FAILURE;
|
||||
file = (mrb_irep_debug_info_file *)mrb_calloc(mrb, 1, sizeof(*file));
|
||||
debug->files[f_idx] = file;
|
||||
|
||||
@@ -338,9 +349,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
|
||||
bin += sizeof(uint8_t);
|
||||
switch (file->line_type) {
|
||||
case mrb_debug_line_ary: {
|
||||
uint32_t l;
|
||||
size_t l = sizeof(uint16_t) * (size_t)file->line_entry_count;
|
||||
|
||||
file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count));
|
||||
if (bin + l > end) return MRB_DUMP_GENERAL_FAILURE;
|
||||
file->lines.ary = (uint16_t *)mrb_malloc(mrb, l);
|
||||
for (l = 0; l < file->line_entry_count; ++l) {
|
||||
file->lines.ary[l] = bin_to_uint16(bin);
|
||||
bin += sizeof(uint16_t);
|
||||
@@ -348,11 +360,12 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
|
||||
} break;
|
||||
|
||||
case mrb_debug_line_flat_map: {
|
||||
uint32_t l;
|
||||
size_t c = (size_t)file->line_entry_count;
|
||||
size_t n = sizeof(mrb_irep_debug_info_line);
|
||||
|
||||
file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_calloc(
|
||||
mrb, (size_t)(file->line_entry_count), sizeof(mrb_irep_debug_info_line));
|
||||
for (l = 0; l < file->line_entry_count; ++l) {
|
||||
if (bin + c*n > end) return MRB_DUMP_GENERAL_FAILURE;
|
||||
file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_calloc(mrb, c, n);
|
||||
for (size_t l = 0; l < file->line_entry_count; ++l) {
|
||||
file->lines.flat_map[l].start_pos = bin_to_uint32(bin);
|
||||
bin += sizeof(uint32_t);
|
||||
file->lines.flat_map[l].line = bin_to_uint16(bin);
|
||||
@@ -361,7 +374,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
|
||||
} break;
|
||||
|
||||
case mrb_debug_line_packed_map: {
|
||||
file->lines.packed_map = (uint8_t*)mrb_calloc(mrb, 1, (size_t)file->line_entry_count);
|
||||
size_t l = (size_t)file->line_entry_count;
|
||||
|
||||
if (bin + l > end) return MRB_DUMP_GENERAL_FAILURE;
|
||||
file->lines.packed_map = (uint8_t*)mrb_calloc(mrb, 1, l);
|
||||
memcpy(file->lines.packed_map, bin, file->line_entry_count);
|
||||
bin += file->line_entry_count;
|
||||
} break;
|
||||
@@ -381,7 +397,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
ret = read_debug_record(mrb, bin, (mrb_irep*)irep->reps[i], &len, filenames, filenames_len);
|
||||
ret = read_debug_record(mrb, bin, end, (mrb_irep*)irep->reps[i], &len, filenames, filenames_len);
|
||||
if (ret != MRB_DUMP_OK) return ret;
|
||||
bin += len;
|
||||
}
|
||||
@@ -394,9 +410,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
|
||||
}
|
||||
|
||||
static int
|
||||
read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
|
||||
read_section_debug(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep *irep, uint8_t flags)
|
||||
{
|
||||
const uint8_t *bin;
|
||||
const uint8_t *end = start + size;
|
||||
ptrdiff_t diff;
|
||||
struct rite_section_debug_header *header;
|
||||
uint16_t i;
|
||||
@@ -412,11 +429,16 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t
|
||||
|
||||
filenames_len = bin_to_uint16(bin);
|
||||
bin += sizeof(uint16_t);
|
||||
if (bin > end) return MRB_DUMP_GENERAL_FAILURE;
|
||||
filenames_obj = mrb_str_new(mrb, NULL, sizeof(mrb_sym) * (size_t)filenames_len);
|
||||
filenames = (mrb_sym*)RSTRING_PTR(filenames_obj);
|
||||
for (i = 0; i < filenames_len; ++i) {
|
||||
uint16_t f_len = bin_to_uint16(bin);
|
||||
bin += sizeof(uint16_t);
|
||||
if (bin + f_len > end) {
|
||||
result = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto debug_exit;
|
||||
}
|
||||
if (flags & FLAG_SRC_MALLOC) {
|
||||
filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len);
|
||||
}
|
||||
@@ -426,7 +448,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t
|
||||
bin += f_len;
|
||||
}
|
||||
|
||||
result = read_debug_record(mrb, bin, irep, &len, filenames, filenames_len);
|
||||
result = read_debug_record(mrb, bin, end, irep, &len, filenames, filenames_len);
|
||||
if (result != MRB_DUMP_OK) goto debug_exit;
|
||||
|
||||
bin += len;
|
||||
@@ -449,6 +471,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec
|
||||
ptrdiff_t diff;
|
||||
int i;
|
||||
|
||||
if (irep->nlocals == 0) return MRB_DUMP_GENERAL_FAILURE;
|
||||
irep->lv = lv = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (irep->nlocals - 1));
|
||||
|
||||
for (i = 0; i + 1 < irep->nlocals; ++i) {
|
||||
@@ -482,9 +505,10 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec
|
||||
}
|
||||
|
||||
static int
|
||||
read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
|
||||
read_section_lv(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep *irep, uint8_t flags)
|
||||
{
|
||||
const uint8_t *bin;
|
||||
const uint8_t *end = start + size;
|
||||
ptrdiff_t diff;
|
||||
struct rite_section_lv_header const *header;
|
||||
uint32_t i;
|
||||
@@ -502,12 +526,13 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t fl
|
||||
|
||||
syms_len = bin_to_uint32(bin);
|
||||
bin += sizeof(uint32_t);
|
||||
if (bin > end) return MRB_DUMP_READ_FAULT;
|
||||
syms_obj = mrb_str_new(mrb, NULL, sizeof(mrb_sym) * (size_t)syms_len);
|
||||
syms = (mrb_sym*)RSTRING_PTR(syms_obj);
|
||||
for (i = 0; i < syms_len; ++i) {
|
||||
uint16_t const str_len = bin_to_uint16(bin);
|
||||
bin += sizeof(uint16_t);
|
||||
|
||||
if (bin > end) return MRB_DUMP_READ_FAULT;
|
||||
syms[i] = intern_func(mrb, (const char*)bin, str_len);
|
||||
bin += str_len;
|
||||
}
|
||||
@@ -577,28 +602,36 @@ read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags)
|
||||
}
|
||||
|
||||
bin += sizeof(struct rite_binary_header);
|
||||
do {
|
||||
bin_size -= sizeof(struct rite_binary_header);
|
||||
while (bin_size > sizeof(struct rite_section_header)) {
|
||||
section_header = (const struct rite_section_header *)bin;
|
||||
uint32_t section_size = bin_to_uint32(section_header->section_size);
|
||||
if (bin_size < section_size) return NULL;
|
||||
if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) {
|
||||
irep = read_section_irep(mrb, bin, flags, &proc);
|
||||
irep = read_section_irep(mrb, bin, bin_size, flags, &proc);
|
||||
if (!irep) return NULL;
|
||||
}
|
||||
else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) {
|
||||
if (!irep) return NULL; /* corrupted data */
|
||||
result = read_section_debug(mrb, bin, irep, flags);
|
||||
result = read_section_debug(mrb, bin, bin_size, irep, flags);
|
||||
if (result < MRB_DUMP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (memcmp(section_header->section_ident, RITE_SECTION_LV_IDENT, sizeof(section_header->section_ident)) == 0) {
|
||||
if (!irep) return NULL;
|
||||
result = read_section_lv(mrb, bin, irep, flags);
|
||||
result = read_section_lv(mrb, bin, bin_size, irep, flags);
|
||||
if (result < MRB_DUMP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
bin += bin_to_uint32(section_header->section_size);
|
||||
} while (memcmp(section_header->section_ident, RITE_BINARY_EOF, sizeof(section_header->section_ident)) != 0);
|
||||
else if (memcmp(section_header->section_ident, RITE_BINARY_EOF, sizeof(section_header->section_ident)) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
bin += section_size;
|
||||
bin_size -= section_size;
|
||||
}
|
||||
|
||||
return proc;
|
||||
}
|
||||
@@ -608,7 +641,7 @@ mrb_proc_read_irep(mrb_state *mrb, const uint8_t *bin)
|
||||
{
|
||||
uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC;
|
||||
|
||||
return read_irep(mrb, bin, (size_t)-1, flags);
|
||||
return read_irep(mrb, bin, (size_t)UINT32_MAX, flags);
|
||||
}
|
||||
|
||||
DEFINE_READ_IREP_FUNC(
|
||||
|
||||
@@ -689,9 +689,11 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
|
||||
regs = mrb->c->ci->stack+1;
|
||||
|
||||
if (n == 0) {
|
||||
argnum_error:
|
||||
mrb_argnum_error(mrb, 0, 1, -1);
|
||||
}
|
||||
else if (n == 15) {
|
||||
if (RARRAY_LEN(regs[0]) == 0) goto argnum_error;
|
||||
name = mrb_obj_to_sym(mrb, RARRAY_PTR(regs[0])[0]);
|
||||
}
|
||||
else {
|
||||
@@ -1359,14 +1361,16 @@ RETRY_TRY_BLOCK:
|
||||
regs[a] = mrb_ary_entry(va, mrb_integer(vb));
|
||||
break;
|
||||
case MRB_TT_HASH:
|
||||
regs[a] = mrb_hash_get(mrb, va, vb);
|
||||
va = mrb_hash_get(mrb, va, vb);
|
||||
regs[a] = va;
|
||||
break;
|
||||
case MRB_TT_STRING:
|
||||
switch (mrb_type(vb)) {
|
||||
case MRB_TT_INTEGER:
|
||||
case MRB_TT_STRING:
|
||||
case MRB_TT_RANGE:
|
||||
regs[a] = mrb_str_aref(mrb, va, vb, mrb_undef_value());
|
||||
va = mrb_str_aref(mrb, va, vb, mrb_undef_value());
|
||||
regs[a] = va;
|
||||
break;
|
||||
default:
|
||||
goto getidx_fallback;
|
||||
@@ -1388,7 +1392,8 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
CASE(OP_GETCONST, BB) {
|
||||
regs[a] = mrb_vm_const_get(mrb, syms[b]);
|
||||
mrb_value v = mrb_vm_const_get(mrb, syms[b]);
|
||||
regs[a] = v;
|
||||
NEXT;
|
||||
}
|
||||
|
||||
@@ -1398,7 +1403,8 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
CASE(OP_GETMCNST, BB) {
|
||||
regs[a] = mrb_const_get(mrb, regs[a], syms[b]);
|
||||
mrb_value v = mrb_const_get(mrb, regs[a], syms[b]);
|
||||
regs[a] = v;
|
||||
NEXT;
|
||||
}
|
||||
|
||||
@@ -1729,6 +1735,7 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
mrb_assert(bidx < irep->nregs);
|
||||
|
||||
blk = regs[bidx];
|
||||
uint8_t nk = (b >> 4) & 0x0f;
|
||||
if (nk > 0 && nk < CALL_MAXARGS) { /* pack keyword arguments */
|
||||
uint8_t n = b & 0x0f;
|
||||
@@ -1737,6 +1744,8 @@ RETRY_TRY_BLOCK:
|
||||
regs[kidx] = kdict;
|
||||
nk = 15;
|
||||
b = n | (nk<<4);
|
||||
bidx = kidx + 1;
|
||||
regs[bidx] = blk;
|
||||
}
|
||||
|
||||
if (mid == 0 || !target_class) {
|
||||
@@ -1744,12 +1753,9 @@ RETRY_TRY_BLOCK:
|
||||
mrb_exc_set(mrb, exc);
|
||||
goto L_RAISE;
|
||||
}
|
||||
if (target_class->flags & MRB_FL_CLASS_IS_PREPENDED) {
|
||||
if ((target_class->flags & MRB_FL_CLASS_IS_PREPENDED) || target_class->tt == MRB_TT_MODULE) {
|
||||
target_class = mrb_vm_ci_target_class(ci);
|
||||
}
|
||||
else if (target_class->tt == MRB_TT_MODULE) {
|
||||
target_class = mrb_vm_ci_target_class(ci);
|
||||
if (target_class->tt != MRB_TT_ICLASS) {
|
||||
if (!target_class || target_class->tt != MRB_TT_ICLASS) {
|
||||
goto super_typeerror;
|
||||
}
|
||||
}
|
||||
@@ -1761,7 +1767,6 @@ RETRY_TRY_BLOCK:
|
||||
mrb_exc_set(mrb, exc);
|
||||
goto L_RAISE;
|
||||
}
|
||||
blk = regs[bidx];
|
||||
if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
|
||||
blk = mrb_type_convert(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc));
|
||||
/* The stack or ci stack might have been reallocated during
|
||||
@@ -2023,14 +2028,15 @@ RETRY_TRY_BLOCK:
|
||||
CASE(OP_KARG, BB) {
|
||||
mrb_value k = mrb_symbol_value(syms[b]);
|
||||
mrb_int kidx = mrb_ci_kidx(mrb->c->ci);
|
||||
mrb_value kdict;
|
||||
mrb_value kdict, v;
|
||||
|
||||
if (kidx < 0 || !mrb_hash_p(kdict=regs[kidx]) || !mrb_hash_key_p(mrb, kdict, k)) {
|
||||
mrb_value str = mrb_format(mrb, "missing keyword: %v", k);
|
||||
mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str));
|
||||
goto L_RAISE;
|
||||
}
|
||||
regs[a] = mrb_hash_get(mrb, kdict, k);
|
||||
v = mrb_hash_get(mrb, kdict, k);
|
||||
regs[a] = v;
|
||||
mrb_hash_delete_key(mrb, kdict, k);
|
||||
NEXT;
|
||||
}
|
||||
@@ -2822,13 +2828,15 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
CASE(OP_RANGE_INC, B) {
|
||||
regs[a] = mrb_range_new(mrb, regs[a], regs[a+1], FALSE);
|
||||
mrb_value v = mrb_range_new(mrb, regs[a], regs[a+1], FALSE);
|
||||
regs[a] = v;
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
CASE(OP_RANGE_EXC, B) {
|
||||
regs[a] = mrb_range_new(mrb, regs[a], regs[a+1], TRUE);
|
||||
mrb_value v = mrb_range_new(mrb, regs[a], regs[a+1], TRUE);
|
||||
regs[a] = v;
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user