summaryrefslogtreecommitdiffhomepage
path: root/src/codedump.c
AgeCommit message (Collapse)Author
2021-12-20codedump.c: adjust the position of local variable labels.Yukihiro "Matz" Matsumoto
2021-12-01codedump.c: print `OP_EXT` explicitly again for debugging purpose.Yukihiro "Matz" Matsumoto
2021-10-21codedump.c: add indentation for `OP_MOVE`.Yukihiro "Matz" Matsumoto
2021-10-19codedump.c: remove `OP_` prefix from disasm output.Yukihiro "Matz" Matsumoto
2021-10-19ops.h: add new instructions `OP_SSEND` and `OP_SSENDB`.Yukihiro "Matz" Matsumoto
These instructions call methods of the receiver.
2021-10-12Support Ruby3.0 keyword arguments.Yukihiro "Matz" Matsumoto
The Difference Since Ruby1.9, the keyword arguments were emulated by Ruby using the hash object at the bottom of the arguments. But we have gradually moved toward keyword arguments separated from normal (positinal) arguments. At the same time, we value compatibility, so that Ruby3.0 keyword arguments are somewhat compromise. Basically, keyword arguments are separated from positional arguments, except when the method does not take any formal keyword arguments, given keyword arguments (packed in the hash object) are considered as the last argument. And we also allow non symbol keys in the keyword arguments. In that case, those keys are just passed in the `**` hash (or raise `ArgumentError` for unknown keys). The Instruction Changes We have changed `OP_SEND` instruction. `OP_SEND` instruction used to take 3 operands, the register, the symbol, the number of (positional) arguments. The meaning of the third operand has been changed. It is now considered as `n|(nk<<4)`, where `n` is the number of positional arguments, and `nk` is the number of keyword arguments, both occupies 4 bits in the operand. The number `15` in both `n` and `nk` means variable sized arguments are packed in the object. Positional arguments will be packed in the array, and keyword arguments will be packed in the hash object. That means arguments more than 14 values are always packed in the object. Arguments information for other instructions (`OP_SENDB` and `OP_SUPER`) are also changed. It works as the third operand of `OP_SEND`. the difference between `OP_SEND` and `OP_SENDB` is just trivial. It assigns `nil` to the block hidden arguments (right after arguments). The instruction `OP_SENDV` and `OP_SENDVB` are removed. Those instructions are replaced by `OP_SEND` and `OP_SENDB` respectively with the `15` (variable sized) argument information. Calling Convention When calling a method, the stack elements shall be in the order of the receiver of the method, positional arguments, keyword arguments and the block argument. If the number of positional or keyword arugument (`n` or `nk`) is zero, corresponding arguments will be empty. So when `n=0` and `nk=0` the stack layout (from bottom to top) will be: +-----------------------+ | recv | block (or nil) | +-----------------------+ The last elements `block` should be explicitly filled before `OP_SEND` or assigned to `nil` by `OP_SENDB` internally. In other words, the following have exactly same behavior: OP_SENDB clears `block` implicitly: ``` OP_SENDB reg sym 0 ``` OP_SEND clears `block` implicitly: ``` OP_LOADNIL R2 OP_SEND R2 sym 0 ``` When calling a method with only positional arguments (n=0..14) without keyword arguments, the stack layout will be like following: +--------------------------------------------+ | recv | arg1 | ... | arg_n | block (or nil) | +--------------------------------------------+ When calling a method with arguments packed in the array (n=15) which means argument splat (*) is used in the actual arguments, or more than 14 arguments are passed the stack layout will be like following: +-------------------------------+ | recv | array | block (or nil) | +-------------------------------+ The number of the actual arguments is determined by the length of the argument array. When keyword arguments are given (nk>0), keyword arguments are passed between positional arguments and the block argument. For example, when we pass one positional argument `1` and one keyword argument `a: 2`, the stack layout will be like: +------------------------------------+ | recv | 1 | :a | 2 | block (or nil) | +------------------------------------+ Note that keyword arguments consume `2*nk` elements in the stack when `nk=0..14` (unpacked). When calling a method with keyword arguments packed in the hash object (nk=15) which means keyword argument splat (**) is used or more than 14 keyword arguments in the actual arguments, the stack layout will be like: +------------------------------+ | recv | hash | block (or nil) | +------------------------------+ Note for mruby/c When mruby/c authors try to support new keyword arguments, they need to handle the new meaning of the argument information operand. If they choose not to support keyword arguments in mruby/c, it just raise error when `nk` (taken by `(c>>4)&0xf`) is not zero. And combine `OP_SENDV` behavior with `OP_SEND` when `n` is `15`. If they want to support keyword arguments seriously, contact me at <[email protected]> or `@yukihiro_matz`. I can help you.
2021-10-06codedump.c: remove trailing extra newline.Yukihiro "Matz" Matsumoto
The bug was introduced in 8be78bd.
2021-10-03mruby/ops.h: add new instructions `OP_GETIDX` and `OP_SETIDX`.Yukihiro "Matz" Matsumoto
Which represent `obj[int]` and `obj[int]=val` respectively where `obj` is either `string`, `array` or `hash`, so that index access could be faster. When `obj` is not assumed type or `R(a+1)` is not integer, the instructions fallback to method calls.
2021-09-20codedump.c: add cosmetic tabs before variable labels.Yukihiro "Matz" Matsumoto
2021-09-19codegen.c: unify `OP_ARYPUSH` and `OP_ARYPUSH_N`.Yukihiro "Matz" Matsumoto
- `OP_ARYPUSH` now takes operand for the number of pushing elements - the code generator consume the stack no more than `64` for `mruby/c`
2021-09-17ops.h: add `OP_ARYPUSH_N` instruction.Yukihiro "Matz" Matsumoto
Add n elements at once. Reduces instructions for huge array initialization. In addition, `gen_value` function in `codegen.c` was refactored and clarified.
2021-09-11codedump.c: avoid printing `OP_EXT?` prefix.Yukihiro "Matz" Matsumoto
2021-09-10vm.c, codedump.c: add `IREP_TT_NFLAG` assertions.Yukihiro "Matz" Matsumoto
The pool specified by `OP_STRING` (and `OP_SYMBOL`) should represent a string, so that `IREP_TT_NFLAG` should be zero.
2021-09-10ops.h: add `OP_SYMBOL` instruction.Yukihiro "Matz" Matsumoto
It generates a symbol by interning from the pool string.
2021-08-11codedump.c: print local variable name for `ADDI/SUBI/ instructions.Yukihiro "Matz" Matsumoto
Recent peephole optimization made `ADDI/SUBI` destinations possibly local variables.
2021-08-07codedump.c: print two operands `R(x)` and `R(x+1)` for clarity.Yukihiro "Matz" Matsumoto
2021-07-30codedump.c: instruction length should be `ilen`, not `iseq`.Yukihiro "Matz" Matsumoto
2021-07-17codedump.c: update some instructions.Yukihiro "Matz" Matsumoto
- OP_GETGV - OP_SETGV - OP_GETSV - OP_SETSV - OP_GETIV - OP_SETIV - OP_GETCV - OP_SETCV - OP_GETCONST - OP_SETCONST - OP_GETMCNST - OP_SETMCNST - OP_GETUPVAR - OP_SETUPVAR
2021-06-30Revert "Remove `OP_EXT[123]` from operands."Yukihiro "Matz" Matsumoto
This reverts commit fd10c7231906ca48cb35892d2a86460004b62249. I thought it was OK to restrict index value within 1 byte, but in some cases index value could be 16 bits (2 bytes). I had several ideas to address the issue, but reverting `fd10c72` is the easiest way. The biggest reason is `mruby/c` still supports `OP_EXT[123]`, so that they don't need any additional work.
2021-06-05codedump.c: fix a compiler condition bug with `MRB_NO_FLOAT`.Yukihiro "Matz" Matsumoto
2021-03-12codegen.c: fixed a typo.Yukihiro "Matz" Matsumoto
2021-03-12codegen.c: no integer overflow error in `codegen`; close #5376Yukihiro "Matz" Matsumoto
Add new pool value type `IREP_TT_BIGINT` and generate integer overflow error in the VM. In the future, `mruby` will support `Bignum` for integers bigger than `mrb_int` (probably using `mpz`).
2021-02-01Allow more than 256 child `irep`; fix #5310Yukihiro "Matz" Matsumoto
We have introduced following new instructions. * `OP_LAMBDA16` * `OP_BLOCK16` * `OP_METHOD16` * `OP_EXEC16` Each instruction uses 16 bits operand for `reps` index. Since new instructions are added, `mruby/c` VM should be updated. Due to new instructions, dump format compatibility is lost, we have increased `RITE_BINARY_MAJOR_VER`. In addition, we have decreased the size of `refcnt` in `mrb_irep` from `uint32_t` to `uint16_t`, which is reasonably big enough.
2021-01-25Silence 'loss of data' warnings.Yukihiro "Matz" Matsumoto
2021-01-03replace ; to : of OPT_SETGV in codedump.cKatsuyoshi Ito
Maybe it's a typo.
2021-01-02Fixed wrong casting in `OP_LOADI32`.Yukihiro "Matz" Matsumoto
Negative integer `>-65535` had wrong value, e,g, `p(-40550)` printed `4294926746` since Nov. 2020, sigh.
2020-12-02Print implicit operands for some instructions.Yukihiro "Matz" Matsumoto
2020-11-30Fixed print catch handler address in codedump; ref #5200dearblue
It became 32 bits in #5200, but only the upper 16 bits were printed.
2020-11-26Make `OP_JMP*` operand address to be relative.Yukihiro "Matz" Matsumoto
Jump target address is `operand (16bit)` + `address of next instruction`. In addition, `ilen` was made `uint32_t` so that `iseq` length limitation of 65536 is removed. Only jump target address should be within signed 16bit (-32768 .. 32767).
2020-11-24Fix compiler errors from `MRB_NO_FLOAT`; #5185Yukihiro "Matz" Matsumoto
Also added `no-float.rb` target in `build_config`.
2020-11-21Rename `MRB_{ENABLE,DISABLE}_` to `MRB_{USE,NO}_`; close #5163KOBAYASHI Shuji
| Previous Name | New Name | |------------------------------|-------------------------| | MRB_ENABLE_ALL_SYMBOLS | MRB_USE_ALL_SYMBOLS | | MRB_ENABLE_SYMBOLL_ALL | MRB_USE_ALL_SYMBOLS | | MRB_ENABLE_CXX_ABI | MRB_USE_CXX_ABI | | MRB_ENABLE_CXX_EXCEPTION | MRB_USE_CXX_EXCEPTION | | MRB_ENABLE_DEBUG_HOOK | MRB_USE_DEBUG_HOOK | | MRB_DISABLE_DIRECT_THREADING | MRB_NO_DIRECT_THREADING | | MRB_DISABLE_STDIO | MRB_NO_STDIO | | ENABLE_LINENOISE | MRB_USE_LINENOISE | | ENABLE_READLINE | MRB_USE_READLINE | | DISABLE_MIRB_UNDERSCORE | MRB_NO_MIRB_UNDERSCORE | | DISABLE_GEMS | MRB_NO_GEMS | * `MRB_ENABLE_SYMBOLL_ALL` seems to be a typo, so it is fixed. * `MRB_` prefix is added to those without. * The previous names can also be used for compatibility.
2020-11-18Check if irep->reps is NULLZhang Xiaohui
2020-11-16Avoid undefined behaviorKOBAYASHI Shuji
### ASAN report (`MRB_INT32`) ```console $ bin/mruby -ve '-0x40000000' mruby 3.0.0preview (2020-10-16) 00001 NODE_SCOPE: 00001 NODE_BEGIN: 00001 NODE_NEGATE: 00001 NODE_INT 40000000 base 16 irep 0x6070000001e0 nregs=2 nlocals=1 pools=0 syms=0 reps=0 iseq=9 file: -e /mruby/src/codedump.c:173:49: runtime error: left shift of 49152 by 16 places cannot be represented in type 'int' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /mruby/src/codedump.c:173:49 in 1 000 OP_LOADI32 R1 -1073741824 1 006 OP_RETURN R1 1 008 OP_STOP /mruby/src/vm.c:1138:7: runtime error: left shift of 49152 by 16 places cannot be represented in type 'mrb_int' (aka 'int') SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /mruby/src/vm.c:1138:7 in ```
2020-11-05Fix a bug with printing `(null)` local variable name for a register.Yukihiro "Matz" Matsumoto
2020-11-04Add a new instruction `OP_LOADI32`.Yukihiro "Matz" Matsumoto
That loads 32 bit integer bypassing pool access.
2020-11-03Add new instructions to handle symbols/literals >255; fix #5109Yukihiro "Matz" Matsumoto
New instructions: * OP_LOADL16 * OP_LOADSYM16 * OP_STRING16 Size of pools, symbols are `int16_t` but offset representation in the bytecode was 8 bits. Size of child `irep` array is `int16_t`, too but this change does not address it.
2020-11-02format '%p' expects argument of type 'void *'; #5107Yukihiro "Matz" Matsumoto
2020-10-12Rename `OP_JUW` instruction to `OP_JMPUW`.Yukihiro "Matz" Matsumoto
2020-10-12Fix typo `_hander` -> `_handler`.Yukihiro "Matz" Matsumoto
2020-10-12Replace global jump with catch handler implementationdearblue
When a global jump occurs, look at the catch handler table to determine where to jump. In that case, `pc` already shows the following instruction, but since the table shows `begin_offset ... end_offset`, the comparison is done with `begin_offset < pc && pc <= end_offset`. If there is a corresponding handler, move `pc` to `handler.target_offset` and continue running the VM. When a global jump across `ensure` is made by `return`, `break`, `next`, `redo` and `retry`, the extended `RBreak` object saves and restores the C-level execution position. This extended `RBreak` can have tag information, which makes it a pseudo coroutine (the "tag" mimics CRuby). The implementation of pseudo coroutines by `RBreak` is summarized by `CHECKPOINT_RESTORE ... CHECKPOINT_MAIN ... CHECKPOINT_END` and `throw_tagged_break` / `unwind_ensure` macros. The restart of processing is branched by `RBREAK_TAG_FOREACH(DISPATCH_CHECKPOINTS)`. - Not only `rescue` blocks but also `ensure` blocks are now sandwiched between `OP_EXCEPT` and `OP_RAISEIF`. - Remove the function `ecall()`. It is no longer necessary to re-enter the VM to perform an "ensure block". This will resolves #1888. - Added instruction `OP_JUW` (Jump while UnWind). It jumps unconditionally like `OP_JMP`, but searches the catch handler table and executes the ensure block. Since it searches the catch handler table, it is much heavier than `OP_JMP`.
2020-10-12Removed push/pop instructions for rescue/ensuredearblue
`OP_PUSHERR`, `OP_POPERR`, `OP_EPUSH` and `OP_EPOP` are removed.
2020-10-12Extended `OP_EXCEPT` and `OP_RAISE` (`OP_RAISEIF`) instructionsdearblue
- `OP_EXCEPT` checks if `mrb->exc` is `NULL`, `MRB_TT_EXCEPTION` or `MRB_TT_BREAK`. If `mrb->exc` is `NULL`, it will be replaced with `nil`. - If `OP_RAISE` is `nil`, it does nothing and the immediately following instruction is executed (like `OP_NOP`). Also, in case of `RBreak` object, it moves to the processing for `break`. With this change, the instruction name is changed from `OP_RAISE` to `OP_RAISEIF`.
2020-10-12Extended mruby binary formatdearblue
The catch handler table is combined with iseq block. This is to prevent the structure from growing by adding a field for the catch handler table to the `mrb_irep` structure. "iseq block" and "catch handler table": [number of catch handler table (2 bytes)] [number of byte code (4 bytes)] [iseq (any bytes)] [catch handlers (multiple of 7 bytes)] catch handler: [catch type (1 byte)] [begin offset (2 bytes)] [end offset (2 bytes)] [target offset (2 bytes)] catch type: enum mrb_catch_type (0 = rescue, 1 = ensure) begin offset: Includes the specified instruction address end offset: Does not include the specified instruction address target offset: replaces pc with the specified instruction address This table is not expanded by `read_irep_record_1()`. The necessary elements are expanded one by one when used.
2020-10-12Check `lv` before printing local variable names.Yukihiro "Matz" Matsumoto
2020-10-12You don't need to keep index in local variables info in `irep`.Yukihiro "Matz" Matsumoto
2020-10-12Remove `OP_EXT[123]` from operands.Yukihiro "Matz" Matsumoto
2020-10-12Clarify the use of `MRB_64BIT` and `MRB_INT64` in `dump.c` and `load.c`.Yukihiro "Matz" Matsumoto
- `MRB_64BIT`: the size of a pointer is 64 bits - `MRB_INT64`: the size of `mrb_int` is 64 bits
2020-10-12Replace entire `irep->pool`.Yukihiro "Matz" Matsumoto
Changes: - `pool format is completely replaced - supported types: `STR`, `INT32`, `INT64`, `FLOAT` - `FLOAT` may be replaced by binary representation in the future - insert `NUL` after string literals in `mrb` files - `irep->pool` no longer store values in `mrb_value` - instead it stores in `mrb_pool_value` - less allocation - `mrb_irep` can be stored in ROM
2020-10-12Constify `irep` members.Yukihiro "Matz" Matsumoto
- `pool` - `syms` - `reps`
2020-05-07Add a new instruction `OP_LOADI16`.Yukihiro "Matz" Matsumoto
Which loads 16bit integer to the register. The instruction number should be reorder on massive instruction refactoring. The instruction is added for `mruby/c` which had performance issue with `OP_EXT`. With this instruction, `mruby/c` VM can just raise errors on `OP_EXT` extension instructions.