Compare commits

...

18 Commits

Author SHA1 Message Date
mimaki b4f36b1ad9 Merge branch 'master' into stable 2023-01-18 10:45:35 +09:00
Yukihiro "Matz" Matsumoto 3a7e138c05 mruby/internal.h: add mrb_env_new to the internal function header 2023-01-18 10:37:48 +09:00
Yukihiro "Matz" Matsumoto e6cf932d38 fixup! mruby/internal.h: add codedump functions to the internal function header 2023-01-18 10:37:48 +09:00
Yukihiro "Matz" Matsumoto 55eea005c8 mruby/internal.h: add codedump functions to the internal function header
ref #5906
2023-01-18 10:37:48 +09:00
mimaki 23aa5f91bc Update version to 3.2.0RC2. 2023-01-18 10:26:58 +09:00
mimaki 830f88c5a0 Merge commit '9deb52c7b2ba6028d996172bfdd6cf8a0405ce1c' into stable 2023-01-18 09:45:23 +09:00
Yukihiro "Matz" Matsumoto 3639feb047 Merge pull request #5908 from dearblue/env-unshare.2
Make `mrb_env_unshare()` call in `mrb_vm_run()`
2023-01-18 08:05:00 +09:00
Yukihiro "Matz" Matsumoto 63597cbbd1 Merge pull request #5910 from mruby/dependabot/github_actions/github/super-linter-4.10.1
build(deps): bump github/super-linter from 4.10.0 to 4.10.1
2023-01-18 07:53:11 +09:00
Yukihiro "Matz" Matsumoto faa6a5cb4f Merge pull request #5906 from AlexDenisov/codedump-to-file
Add ability to dump bytecode into an arbitrary file
2023-01-18 07:37:12 +09:00
AlexDenisov e15288e460 Add ability to dump bytecode into an arbitrary file 2023-01-17 19:01:55 +01:00
dependabot[bot] 823b8e4148 build(deps): bump github/super-linter from 4.10.0 to 4.10.1
Bumps [github/super-linter](https://github.com/github/super-linter) from 4.10.0 to 4.10.1.
- [Release notes](https://github.com/github/super-linter/releases)
- [Changelog](https://github.com/github/super-linter/blob/main/docs/release-process.md)
- [Commits](https://github.com/github/super-linter/compare/v4.10.0...v4.10.1)

---
updated-dependencies:
- dependency-name: github/super-linter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-17 14:01:22 +00:00
Yukihiro "Matz" Matsumoto 9deb52c7b2 mruby-io/io.c: allow disabling popen
When `MRB_NO_IO_POPEN` is defined (or iPhone is target), `IO#popen`
will be disabled.
2023-01-17 18:25:23 +09:00
Yukihiro "Matz" Matsumoto 6b87aae757 doc/guides/compile.md: update compilation example
Show usage of multiple command-line options to `mruby-config`.
2023-01-17 18:23:29 +09:00
Yukihiro "Matz" Matsumoto 10768c1191 LEGAL: add entries for non-MIT licensed files. 2023-01-17 18:23:29 +09:00
Yukihiro "Matz" Matsumoto 2c261503b5 doc/internal/boxing.md: remove an extra double quote sign. 2023-01-16 19:01:11 +09:00
Yukihiro "Matz" Matsumoto 7a6d03f869 vm.c: transferred fiber termination should kick root fiber; fix #5907 2023-01-16 18:25:50 +09:00
Yukihiro "Matz" Matsumoto 3f6fd994f0 README.md: mruby is not Ruby 3.x compatible (for syntax at least)
With pattern matching as an exception.
2023-01-16 14:39:47 +09:00
dearblue 365c151df0 Make mrb_env_unshare() call in mrb_vm_run()
Move the detachment of the "env" object, now done by `mrb_top_run()` by #5904, to `mrb_vm_run()`.
This is because `mrb_vm_run()` can remove `mrb_env_unshare()` which is called from `bin/mirb`.

Also, even if the mruby VM is already running, either of the following conditions should be used to detach "env":
  - If the `stack_keep` variable is 0.
  - If the stack length of "env" is longer than `irep->nlocals`.

The reason for the change is that the stack beyond `irep->nlocals` is used inside the called method, and previously it was possible to reference and manipulate the state inside the method via "env".

    env stack       |                           |

    main stack      | top |  m1  |    m2    |
                          |<--------------->|
                            operable via env stack (including self)

If the problematic block is called from the `m2` method above, it is possible to replace `self` in `m1` and `m2` as well as the internal variables.

This change may cause compatibility problems, but I believe it is better to make `MRB_API`, `mrb_vm_run()` safe.
If a dangerous procedure is absolutely necessary, `mrb_vm_exec()` can still be called as before.
2023-01-15 18:16:42 +09:00
15 changed files with 2026 additions and 1592 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
# Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0
- name: Lint Code Base
uses: github/super-linter/slim@v4.10.0
uses: github/super-linter/slim@v4.10.1
env:
ERROR_ON_MISSING_EXEC_BIT: true
VALIDATE_BASH: true
+35
View File
@@ -3,3 +3,38 @@ LEGAL NOTICE INFORMATION
All the files in this distribution are covered under the MIT license
(see the file LICENSE) except some files mentioned below:
- src/readfloat.c: public domain by Yasuhiro Matsumoto (@mattn)
- src/fmt_fp.c: public domain by Dave Hylands (@dhylands)
- mrbgems/mruby-dir/src/Win/dirent.c: MIT-like license by Kevlin Henney
[src/readfloat.c]
strtod implementation.
author: Yasuhiro Matsumoto (@mattn)
license: public domain
The original code can be found in https://github.com/mattn/strtod
[src/fmt_fp.c]
The code in this function was inspired from Fred Bayer's pdouble.c.
Since pdouble.c was released as Public Domain, I'm releasing this
code as public domain as well.
Dave Hylands
The original code can be found in https://github.com/dhylands/format-float
[mrbgems/mruby-dir/src/Win/dirent.c] used only for Windows platform
Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee, provided
that this copyright and permissions notice appear in all copies and
derivatives.
This software is supplied "as is" without express or implied warranty.
But that said, if there are any problems please get in touch.
+3 -2
View File
@@ -5,7 +5,8 @@
## What is mruby
mruby is the lightweight implementation of the Ruby language complying to (part
of) the [ISO standard][ISO-standard]. Its syntax is Ruby 2.x compatible.
of) the [ISO standard][ISO-standard] with more recent features provided by Ruby 3.x.
Also, its syntax is Ruby 3.x compatible except for pattern matching.
mruby can be linked and embedded within your application. We provide the
interpreter program "mruby", and the interactive mruby shell "mirb" as examples.
@@ -19,7 +20,7 @@ of the Ministry of Economy, Trade and Industry of Japan.
## How to get mruby
The release candidate version 3.2.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.2.0-rc.zip](https://github.com/mruby/mruby/archive/3.2.0-rc.zip)
The release candidate version 3.2.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.2.0-rc2.zip](https://github.com/mruby/mruby/archive/3.2.0-rc2.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)
+1 -1
View File
@@ -545,7 +545,7 @@ For example, when you have a C source file (`c.c`) and try to
compile and link it with `libmruby.a`, you can run the following command,
```
gcc `mruby-config --cflags` c.c `mruby-config --ldflags` `mruby-config --libs`
`mruby-config --cc --cflags` c.c `mruby-config --ldflags --libs`
```
When you use `make`, add following lines in `Makefile`
+1 -1
View File
@@ -45,7 +45,7 @@ The NaN boxing packing bit patterns are like following:
| ptr | `01111111 11111100 PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPP01` |
| nil | `00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000` |
The object values appear far more frequently than floating-point numbers, so we offset the value so that object pointers are unchanged. This technique is called "favor pointer"".
The object values appear far more frequently than floating-point numbers, so we offset the value so that object pointers are unchanged. This technique is called "favor pointer".
## No Boxing
+7
View File
@@ -38,6 +38,12 @@ int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *
#endif
#endif
/* codedump */
void mrb_codedump_all(mrb_state *mrb, struct RProc *proc);
#ifndef MRB_NO_STDIO
void mrb_codedump_all_file(mrb_state *mrb, struct RProc *proc, FILE *out);
#endif
/* error */
mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
@@ -104,6 +110,7 @@ void mrb_rational_copy(mrb_state *mrb, mrb_value x, mrb_value y);
struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*);
void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b);
mrb_int mrb_proc_arity(const struct RProc *p);
struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc);
#endif
/* range */
+2 -2
View File
@@ -57,7 +57,7 @@ MRB_BEGIN_DECL
/*
* Patch level string. (optional)
*/
#define MRUBY_PATCHLEVEL_STR "RC"
#define MRUBY_PATCHLEVEL_STR "RC2"
#ifndef MRUBY_PATCHLEVEL_STR
# if MRUBY_PATCHLEVEL < 0
@@ -90,7 +90,7 @@ MRB_BEGIN_DECL
/*
* Release day.
*/
#define MRUBY_RELEASE_DAY 13
#define MRUBY_RELEASE_DAY 18
/*
* Release date as a string.
+1 -2
View File
@@ -20,6 +20,7 @@
#include <mruby/variable.h>
#include <mruby/error.h>
#include <mruby/presym.h>
#include <mruby/internal.h>
#include <stdlib.h>
#include <string.h>
@@ -380,8 +381,6 @@ print_cmdline(int code_block_open)
}
#endif
void mrb_codedump_all(mrb_state*, struct RProc*);
static int
check_keyword(const char *buf, const char *word)
{
-1
View File
@@ -6627,7 +6627,6 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt)
}
}
void mrb_codedump_all(mrb_state*, struct RProc*);
void mrb_parser_dump(mrb_state *mrb, node *tree, int offset);
MRB_API void
File diff suppressed because it is too large Load Diff
-3
View File
@@ -9,9 +9,6 @@
#include <mruby/variable.h>
#include <mruby/internal.h>
struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc);
void mrb_codedump_all(mrb_state*, struct RProc*);
static struct RProc*
create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line)
{
+9 -1
View File
@@ -90,6 +90,11 @@ io_get_open_fptr(mrb_state *mrb, mrb_value io)
return fptr;
}
#if !defined(MRB_NO_IO_POPEN) && defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
# define MRB_NO_IO_POPEN 1
#endif
#ifndef MRB_NO_IO_POEPN
static void
io_set_process_status(mrb_state *mrb, pid_t pid, int status)
{
@@ -110,6 +115,7 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status)
}
mrb_gv_set(mrb, mrb_intern_lit(mrb, "$?"), v);
}
#endif
static int
io_modestr_to_flags(mrb_state *mrb, const char *mode)
@@ -333,7 +339,7 @@ io_alloc(mrb_state *mrb)
#define NOFILE 64
#endif
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#ifdef NO_IO_POPEN
# define io_s_popen mrb_notimplement_m
#else
static int
@@ -764,6 +770,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
fptr->fd2 = -1;
}
#ifndef NO_IO_POPEN
if (fptr->pid != 0) {
#if !defined(_WIN32) && !defined(_WIN64)
pid_t pid;
@@ -785,6 +792,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
fptr->pid = 0;
/* Note: we don't raise an exception when waitpid(3) fails */
}
#endif
if (fptr->buf) {
mrb_free(mrb, fptr->buf);
+226 -219
View File
@@ -9,85 +9,85 @@
#ifndef MRB_NO_STDIO
static void
print_r(mrb_state *mrb, const mrb_irep *irep, size_t n)
print_r(mrb_state *mrb, const mrb_irep *irep, size_t n, FILE *out)
{
if (n == 0) return;
if (n >= irep->nlocals) return;
if (!irep->lv[n-1]) return;
printf(" R%d:%s", (int)n, mrb_sym_dump(mrb, irep->lv[n-1]));
fprintf(out, " R%d:%s", (int)n, mrb_sym_dump(mrb, irep->lv[n-1]));
}
static void
print_lv_a(mrb_state *mrb, const mrb_irep *irep, uint16_t a)
print_lv_a(mrb_state *mrb, const mrb_irep *irep, uint16_t a, FILE *out)
{
if (!irep->lv || a >= irep->nlocals || a == 0) {
printf("\n");
fprintf(out, "\n");
return;
}
printf("\t;");
print_r(mrb, irep, a);
printf("\n");
fprintf(out, "\t;");
print_r(mrb, irep, a, out);
fprintf(out, "\n");
}
static void
print_lv_ab(mrb_state *mrb, const mrb_irep *irep, uint16_t a, uint16_t b)
print_lv_ab(mrb_state *mrb, const mrb_irep *irep, uint16_t a, uint16_t b, FILE *out)
{
if (!irep->lv || (a >= irep->nlocals && b >= irep->nlocals) || a+b == 0) {
printf("\n");
fprintf(out, "\n");
return;
}
printf("\t;");
if (a > 0) print_r(mrb, irep, a);
if (b > 0) print_r(mrb, irep, b);
printf("\n");
fprintf(out, "\t;");
if (a > 0) print_r(mrb, irep, a, out);
if (b > 0) print_r(mrb, irep, b, out);
fprintf(out, "\n");
}
static void
print_header(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t i)
print_header(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t i, FILE *out)
{
int32_t line;
mrb_assert(i <= UINT32_MAX);
line = mrb_debug_get_line(mrb, irep, (uint32_t)i);
if (line < 0) {
printf(" ");
fprintf(out, " ");
}
else {
printf("%5d ", line);
fprintf(out, "%5d ", line);
}
printf("%03d ", (int)i);
fprintf(out, "%03d ", (int)i);
}
static void
print_args(uint16_t i)
print_args(uint16_t i, FILE *out)
{
mrb_assert(i <= 255);
uint8_t n = i&0xf;
uint8_t nk = (i>>4)&0xf;
if (n == 15) {
printf("n=*");
fprintf(out, "n=*");
}
else {
printf("n=%d", n);
fprintf(out, "n=%d", n);
}
if (nk > 0) {
printf("|");
fprintf(out, "|");
if (nk == 15) {
printf("nk=*");
fprintf(out, "nk=*");
}
else {
printf("nk=%d", nk);
fprintf(out, "nk=%d", nk);
}
}
printf("\n");
fprintf(out, "\n");
}
#define CASE(insn,ops) case insn: FETCH_ ## ops (); L_ ## insn
static void
codedump(mrb_state *mrb, const mrb_irep *irep)
codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out)
{
int ai;
const mrb_code *pc, *pcend;
@@ -95,8 +95,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
const char *file = NULL, *next_file;
if (!irep) return;
printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d ilen=%d\n", (void*)irep,
irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen);
fprintf(out, "irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d ilen=%d\n", (void*)irep,
irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen);
if (irep->lv) {
int i;
@@ -107,9 +107,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
if (s) {
if (!head) {
head = TRUE;
printf("local variable names:\n");
fprintf(out, "local variable names:\n");
}
printf(" R%d:%s\n", i, s);
fprintf(out, " R%d:%s\n", i, s);
}
}
}
@@ -138,7 +138,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
type = buf;
break;
}
printf("catch type: %-8s begin: %04" PRIu32 " end: %04" PRIu32 " target: %04" PRIu32 "\n", type, begin, end, target);
fprintf(out, "catch type: %-8s begin: %04" PRIu32 " end: %04" PRIu32 " target: %04" PRIu32 "\n", type, begin, end, target);
}
}
@@ -155,60 +155,60 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
i = pc - irep->iseq;
next_file = mrb_debug_get_filename(mrb, irep, (uint32_t)i);
if (next_file && file != next_file) {
printf("file: %s\n", next_file);
fprintf(out, "file: %s\n", next_file);
file = next_file;
}
print_header(mrb, irep, i);
print_header(mrb, irep, i, out);
ins = READ_B();
switch (ins) {
CASE(OP_NOP, Z):
printf("NOP\n");
fprintf(out, "NOP\n");
break;
CASE(OP_MOVE, BB):
printf("MOVE\t\tR%d\tR%d\t", a, b);
print_lv_ab(mrb, irep, a, b);
fprintf(out, "MOVE\t\tR%d\tR%d\t", a, b);
print_lv_ab(mrb, irep, a, b, out);
break;
CASE(OP_LOADL, BB):
switch (irep->pool[b].tt) {
#ifndef MRB_NO_FLOAT
case IREP_TT_FLOAT:
printf("LOADL\t\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f);
fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f);
break;
#endif
case IREP_TT_INT32:
printf("LOADL\t\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32);
fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32);
break;
#ifdef MRB_64BIT
case IREP_TT_INT64:
printf("LOADL\t\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64);
fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64);
break;
#endif
default:
printf("LOADL\t\tR%d\tL(%d)\t", a, b);
fprintf(out, "LOADL\t\tR%d\tL(%d)\t", a, b);
break;
}
print_lv_a(mrb, irep, a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADI, BB):
printf("LOADI\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADI\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADINEG, BB):
printf("LOADINEG\tR%d\t-%d\t", a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADINEG\tR%d\t-%d\t", a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADI16, BS):
printf("LOADI16\tR%d\t%d\t", a, (int)(int16_t)b);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADI16\tR%d\t%d\t", a, (int)(int16_t)b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADI32, BSS):
printf("LOADI32\tR%d\t%d\t", a, (int32_t)(((uint32_t)b<<16)+c));
print_lv_a(mrb, irep, a);
fprintf(out, "LOADI32\tR%d\t%d\t", a, (int32_t)(((uint32_t)b<<16)+c));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADI__1, B):
printf("LOADI__1\tR%d\t(-1)\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADI__1\tR%d\t(-1)\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADI_0, B): goto L_LOADI;
CASE(OP_LOADI_1, B): goto L_LOADI;
@@ -220,366 +220,366 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
CASE(OP_LOADI_7, B):
L_LOADI:
b = ins-(int)OP_LOADI_0;
printf("LOADI_%d\tR%d\t(%d)\t", b, a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADI_%d\tR%d\t(%d)\t", b, a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADSYM, BB):
printf("LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADNIL, B):
printf("LOADNIL\tR%d\t(nil)\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADNIL\tR%d\t(nil)\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADSELF, B):
printf("LOADSELF\tR%d\t(R0)\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADSELF\tR%d\t(R0)\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADT, B):
printf("LOADT\t\tR%d\t(true)\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADT\t\tR%d\t(true)\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LOADF, B):
printf("LOADF\t\tR%d\t(false)\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "LOADF\t\tR%d\t(false)\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETGV, BB):
printf("GETGV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "GETGV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SETGV, BB):
printf("SETGV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a);
fprintf(out, "SETGV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETSV, BB):
printf("GETSV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "GETSV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SETSV, BB):
printf("SETSV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a);
fprintf(out, "SETSV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETCONST, BB):
printf("GETCONST\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "GETCONST\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SETCONST, BB):
printf("SETCONST\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a);
fprintf(out, "SETCONST\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETMCNST, BB):
printf("GETMCNST\tR%d\tR%d::%s\t", a, a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "GETMCNST\tR%d\tR%d::%s\t", a, a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SETMCNST, BB):
printf("SETMCNST\tR%d::%s\tR%d\t", a+1, mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a);
fprintf(out, "SETMCNST\tR%d::%s\tR%d\t", a+1, mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETIV, BB):
printf("GETIV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "GETIV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SETIV, BB):
printf("SETIV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a);
fprintf(out, "SETIV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETUPVAR, BBB):
printf("GETUPVAR\tR%d\t%d\t%d\t", a, b, c);
print_lv_a(mrb, irep, a);
fprintf(out, "GETUPVAR\tR%d\t%d\t%d\t", a, b, c);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SETUPVAR, BBB):
printf("SETUPVAR\tR%d\t%d\t%d\t", a, b, c);
print_lv_a(mrb, irep, a);
fprintf(out, "SETUPVAR\tR%d\t%d\t%d\t", a, b, c);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETCV, BB):
printf("GETCV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "GETCV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SETCV, BB):
printf("SETCV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a);
fprintf(out, "SETCV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_GETIDX, B):
printf("GETIDX\tR%d\tR%d\n", a, a+1);
fprintf(out, "GETIDX\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_SETIDX, B):
printf("SETIDX\tR%d\tR%d\tR%d\n", a, a+1, a+2);
fprintf(out, "SETIDX\tR%d\tR%d\tR%d\n", a, a+1, a+2);
break;
CASE(OP_JMP, S):
i = pc - irep->iseq;
printf("JMP\t\t%03d\n", (int)i+(int16_t)a);
fprintf(out, "JMP\t\t%03d\n", (int)i+(int16_t)a);
break;
CASE(OP_JMPUW, S):
i = pc - irep->iseq;
printf("JMPUW\t\t%03d\n", (int)i+(int16_t)a);
fprintf(out, "JMPUW\t\t%03d\n", (int)i+(int16_t)a);
break;
CASE(OP_JMPIF, BS):
i = pc - irep->iseq;
printf("JMPIF\t\tR%d\t%03d\t", a, (int)i+(int16_t)b);
print_lv_a(mrb, irep, a);
fprintf(out, "JMPIF\t\tR%d\t%03d\t", a, (int)i+(int16_t)b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_JMPNOT, BS):
i = pc - irep->iseq;
printf("JMPNOT\tR%d\t%03d\t", a, (int)i+(int16_t)b);
print_lv_a(mrb, irep, a);
fprintf(out, "JMPNOT\tR%d\t%03d\t", a, (int)i+(int16_t)b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_JMPNIL, BS):
i = pc - irep->iseq;
printf("JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b);
print_lv_a(mrb, irep, a);
fprintf(out, "JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SSEND, BBB):
printf("SSEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c);
fprintf(out, "SSEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c, out);
break;
CASE(OP_SSENDB, BBB):
printf("SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c);
fprintf(out, "SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c, out);
break;
CASE(OP_SEND, BBB):
printf("SEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c);
fprintf(out, "SEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c, out);
break;
CASE(OP_SENDB, BBB):
printf("SENDB\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c);
fprintf(out, "SENDB\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c, out);
break;
CASE(OP_CALL, Z):
printf("CALL\n");
fprintf(out, "CALL\n");
break;
CASE(OP_SUPER, BB):
printf("SUPER\t\tR%d\t", a);
print_args(b);
fprintf(out, "SUPER\t\tR%d\t", a);
print_args(b, out);
break;
CASE(OP_ARGARY, BS):
printf("ARGARY\tR%d\t%d:%d:%d:%d (%d)\t", a,
fprintf(out, "ARGARY\tR%d\t%d:%d:%d:%d (%d)\t", a,
(b>>11)&0x3f,
(b>>10)&0x1,
(b>>5)&0x1f,
(b>>4)&0x1,
(b>>0)&0xf);
print_lv_a(mrb, irep, a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_ENTER, W):
printf("ENTER\t\t%d:%d:%d:%d:%d:%d:%d (0x%x)\n",
MRB_ASPEC_REQ(a),
MRB_ASPEC_OPT(a),
MRB_ASPEC_REST(a),
MRB_ASPEC_POST(a),
MRB_ASPEC_KEY(a),
MRB_ASPEC_KDICT(a),
MRB_ASPEC_BLOCK(a), a);
fprintf(out, "ENTER\t\t%d:%d:%d:%d:%d:%d:%d (0x%x)\n",
MRB_ASPEC_REQ(a),
MRB_ASPEC_OPT(a),
MRB_ASPEC_REST(a),
MRB_ASPEC_POST(a),
MRB_ASPEC_KEY(a),
MRB_ASPEC_KDICT(a),
MRB_ASPEC_BLOCK(a), a);
break;
CASE(OP_KEY_P, BB):
printf("KEY_P\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "KEY_P\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_KEYEND, Z):
printf("KEYEND\n");
fprintf(out, "KEYEND\n");
break;
CASE(OP_KARG, BB):
printf("KARG\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "KARG\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_RETURN, B):
printf("RETURN\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "RETURN\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_RETURN_BLK, B):
printf("RETURN_BLK\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "RETURN_BLK\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_BREAK, B):
printf("BREAK\t\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "BREAK\t\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_BLKPUSH, BS):
printf("BLKPUSH\tR%d\t%d:%d:%d:%d (%d)\t", a,
fprintf(out, "BLKPUSH\tR%d\t%d:%d:%d:%d (%d)\t", a,
(b>>11)&0x3f,
(b>>10)&0x1,
(b>>5)&0x1f,
(b>>4)&0x1,
(b>>0)&0xf);
print_lv_a(mrb, irep, a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_LAMBDA, BB):
printf("LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]);
fprintf(out, "LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]);
break;
CASE(OP_BLOCK, BB):
printf("BLOCK\t\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]);
fprintf(out, "BLOCK\t\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]);
break;
CASE(OP_METHOD, BB):
printf("METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]);
fprintf(out, "METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]);
break;
CASE(OP_RANGE_INC, B):
printf("RANGE_INC\tR%d\n", a);
fprintf(out, "RANGE_INC\tR%d\n", a);
break;
CASE(OP_RANGE_EXC, B):
printf("RANGE_EXC\tR%d\n", a);
fprintf(out, "RANGE_EXC\tR%d\n", a);
break;
CASE(OP_DEF, BB):
printf("DEF\t\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
fprintf(out, "DEF\t\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
break;
CASE(OP_UNDEF, B):
printf("UNDEF\t\t:%s\n", mrb_sym_dump(mrb, irep->syms[a]));
fprintf(out, "UNDEF\t\t:%s\n", mrb_sym_dump(mrb, irep->syms[a]));
break;
CASE(OP_ALIAS, BB):
printf("ALIAS\t\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b]));
fprintf(out, "ALIAS\t\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b]));
break;
CASE(OP_ADD, B):
printf("ADD\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "ADD\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_ADDI, BB):
printf("ADDI\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "ADDI\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SUB, B):
printf("SUB\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "SUB\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_SUBI, BB):
printf("SUBI\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "SUBI\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_MUL, B):
printf("MUL\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "MUL\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_DIV, B):
printf("DIV\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "DIV\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_LT, B):
printf("LT\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "LT\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_LE, B):
printf("LE\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "LE\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_GT, B):
printf("GT\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "GT\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_GE, B):
printf("GE\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "GE\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_EQ, B):
printf("EQ\t\tR%d\tR%d\n", a, a+1);
fprintf(out, "EQ\t\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_ARRAY, BB):
printf("ARRAY\t\tR%d\tR%d\t%d", a, a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "ARRAY\t\tR%d\tR%d\t%d", a, a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_ARRAY2, BBB):
printf("ARRAY\t\tR%d\tR%d\t%d", a, b, c);
print_lv_ab(mrb, irep, a, b);
fprintf(out, "ARRAY\t\tR%d\tR%d\t%d", a, b, c);
print_lv_ab(mrb, irep, a, b, out);
break;
CASE(OP_ARYCAT, B):
printf("ARYCAT\tR%d\tR%d\t", a, a+1);
print_lv_a(mrb, irep, a);
fprintf(out, "ARYCAT\tR%d\tR%d\t", a, a+1);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_ARYPUSH, BB):
printf("ARYPUSH\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "ARYPUSH\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_ARYSPLAT, B):
printf("ARYSPLAT\tR%d\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "ARYSPLAT\tR%d\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_AREF, BBB):
printf("AREF\t\tR%d\tR%d\t%d", a, b, c);
print_lv_ab(mrb, irep, a, b);
fprintf(out, "AREF\t\tR%d\tR%d\t%d", a, b, c);
print_lv_ab(mrb, irep, a, b, out);
break;
CASE(OP_ASET, BBB):
printf("ASET\t\tR%d\tR%d\t%d", a, b, c);
print_lv_ab(mrb, irep, a, b);
fprintf(out, "ASET\t\tR%d\tR%d\t%d", a, b, c);
print_lv_ab(mrb, irep, a, b, out);
break;
CASE(OP_APOST, BBB):
printf("APOST\t\tR%d\t%d\t%d", a, b, c);
print_lv_a(mrb, irep, a);
fprintf(out, "APOST\t\tR%d\t%d\t%d", a, b, c);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_INTERN, B):
printf("INTERN\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "INTERN\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SYMBOL, BB):
mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0);
printf("SYMBOL\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str);
print_lv_a(mrb, irep, a);
fprintf(out, "SYMBOL\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_STRING, BB):
mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0);
printf("STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str);
print_lv_a(mrb, irep, a);
fprintf(out, "STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_STRCAT, B):
printf("STRCAT\tR%d\tR%d\t", a, a+1);
print_lv_a(mrb, irep, a);
fprintf(out, "STRCAT\tR%d\tR%d\t", a, a+1);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_HASH, BB):
printf("HASH\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "HASH\t\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_HASHADD, BB):
printf("HASHADD\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a);
fprintf(out, "HASHADD\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_HASHCAT, B):
printf("HASHCAT\tR%d\tR%d\t", a, a+1);
print_lv_a(mrb, irep, a);
fprintf(out, "HASHCAT\tR%d\tR%d\t", a, a+1);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_OCLASS, B):
printf("OCLASS\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "OCLASS\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_CLASS, BB):
printf("CLASS\t\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "CLASS\t\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_MODULE, BB):
printf("MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a);
fprintf(out, "MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_EXEC, BB):
printf("EXEC\t\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]);
print_lv_a(mrb, irep, a);
fprintf(out, "EXEC\t\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_SCLASS, B):
printf("SCLASS\t\tR%d\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "SCLASS\t\tR%d\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_TCLASS, B):
printf("TCLASS\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "TCLASS\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_ERR, B):
if ((irep->pool[a].tt & IREP_TT_NFLAG) == 0) {
printf("ERR\t\t%s\n", irep->pool[a].u.str);
fprintf(out, "ERR\t\t%s\n", irep->pool[a].u.str);
}
else {
printf("ERR\tL(%d)\n", a);
fprintf(out, "ERR\tL(%d)\n", a);
}
break;
CASE(OP_EXCEPT, B):
printf("EXCEPT\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "EXCEPT\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_RESCUE, BB):
printf("RESCUE\tR%d\tR%d", a, b);
print_lv_ab(mrb, irep, a, b);
fprintf(out, "RESCUE\tR%d\tR%d", a, b);
print_lv_ab(mrb, irep, a, b, out);
break;
CASE(OP_RAISEIF, B):
printf("RAISEIF\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
fprintf(out, "RAISEIF\tR%d\t\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_DEBUG, BBB):
printf("DEBUG\t\t%d\t%d\t%d\n", a, b, c);
fprintf(out, "DEBUG\t\t%d\t%d\t%d\n", a, b, c);
break;
CASE(OP_STOP, Z):
printf("STOP\n");
fprintf(out, "STOP\n");
break;
CASE(OP_EXT1, Z):
printf("EXT1\n");
print_header(mrb, irep, pc-irep->iseq);
fprintf(out, "EXT1\n");
print_header(mrb, irep, pc-irep->iseq, out);
ins = READ_B();
switch (ins) {
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); goto L_OP_ ## i;
@@ -588,8 +588,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
}
break;
CASE(OP_EXT2, Z):
printf("EXT2\n");
print_header(mrb, irep, pc-irep->iseq);
fprintf(out, "EXT2\n");
print_header(mrb, irep, pc-irep->iseq, out);
ins = READ_B();
switch (ins) {
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); goto L_OP_ ## i;
@@ -598,8 +598,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
}
break;
CASE(OP_EXT3, Z):
printf("EXT3\n");
print_header(mrb, irep, pc-irep->iseq);
fprintf(out, "EXT3\n");
print_header(mrb, irep, pc-irep->iseq, out);
ins = READ_B();
switch (ins) {
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); goto L_OP_ ## i;
@@ -609,32 +609,39 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
break;
default:
printf("unknown_op (0x%x)\n", ins);
fprintf(out, "unknown_op (0x%x)\n", ins);
break;
}
mrb_gc_arena_restore(mrb, ai);
}
printf("\n");
fprintf(out, "\n");
}
static void
codedump_recur(mrb_state *mrb, const mrb_irep *irep)
codedump_recur(mrb_state *mrb, const mrb_irep *irep, FILE *out)
{
int i;
codedump(mrb, irep);
codedump(mrb, irep, out);
if (irep->reps) {
for (i=0; i<irep->rlen; i++) {
codedump_recur(mrb, irep->reps[i]);
codedump_recur(mrb, irep->reps[i], out);
}
}
}
void
mrb_codedump_all_file(mrb_state *mrb, struct RProc *proc, FILE *out)
{
codedump_recur(mrb, proc->body.irep, out);
}
#endif
void
mrb_codedump_all(mrb_state *mrb, struct RProc *proc)
{
#ifndef MRB_NO_STDIO
codedump_recur(mrb, proc->body.irep);
mrb_codedump_all_file(mrb, proc, stdout);
#endif
}
-2
View File
@@ -669,8 +669,6 @@ irep_error(mrb_state *mrb)
mrb_exc_set(mrb, mrb_exc_new_lit(mrb, E_SCRIPT_ERROR, "irep load error"));
}
void mrb_codedump_all(mrb_state*, struct RProc*);
static mrb_value
load_irep(mrb_state *mrb, struct RProc *proc, mrbc_context *c)
{
+18 -10
View File
@@ -1269,6 +1269,13 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta
}
if (stack_keep > nregs)
nregs = stack_keep;
else {
struct REnv *e = CI_ENV(mrb->c->ci);
if (stack_keep == 0 || (e && irep->nlocals < MRB_ENV_LEN(e))) {
mrb_vm_ci_env_set(mrb->c->ci, NULL);
mrb_env_unshare(mrb, e, FALSE);
}
}
mrb_stack_extend(mrb, nregs);
stack_clear(c->ci->stack + stack_keep, nregs - stack_keep);
c->ci->stack[0] = self;
@@ -2179,8 +2186,8 @@ RETRY_TRY_BLOCK:
c->status = MRB_FIBER_TERMINATED;
mrb->c = c->prev;
c->prev = NULL;
if (!mrb->c) mrb->c = mrb->root_c;
else c->prev = NULL;
goto L_RAISE;
}
}
@@ -2257,11 +2264,17 @@ RETRY_TRY_BLOCK:
struct mrb_context *c;
c = mrb->c;
if (!c->prev) { /* toplevel return */
regs[irep->nlocals] = v;
goto CHECKPOINT_LABEL_MAKE(RBREAK_TAG_STOP);
if (!c->prev) {
if (c != mrb->root_c) {
/* fiber termination should transfer to root */
c->prev = mrb->root_c;
}
else { /* toplevel return */
regs[irep->nlocals] = v;
goto CHECKPOINT_LABEL_MAKE(RBREAK_TAG_STOP);
}
}
if (!c->vmexec && c->prev->ci == c->prev->cibase) {
else if (!c->vmexec && c->prev->ci == c->prev->cibase) {
RAISE_LIT(mrb, E_FIBER_ERROR, "double resume");
}
CHECKPOINT_RESTORE(RBREAK_TAG_RETURN_TOPLEVEL) {
@@ -3096,11 +3109,6 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st
return mrb_vm_run(mrb, proc, self, stack_keep);
}
if (mrb->c->ci == mrb->c->cibase) {
if (stack_keep == 0) {
struct REnv *e = mrb_vm_ci_env(mrb->c->ci);
mrb_vm_ci_env_set(mrb->c->ci, NULL);
mrb_env_unshare(mrb, e, FALSE);
}
return mrb_vm_run(mrb, proc, self, stack_keep);
}
cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, NULL, 0, 0);