Compare commits

...

33 Commits

Author SHA1 Message Date
mimaki 6b82843e72 Update version to 3.2.0RC3. 2023-01-23 10:16:15 +09:00
mimaki b40ab7bfee Merge branch 'master' into stable 2023-01-23 09:54:02 +09:00
Yukihiro "Matz" Matsumoto aefc5befbd mruby-io/io.c: fix issues with gets; fix #5913
- gets with RS multiple times
- gets with RS with limit
- gets with limit bigger than buffer size
2023-01-23 07:30:40 +09:00
Yukihiro "Matz" Matsumoto be5266fbe6 mruby-io/test: test gets with RS multiple times; ref #5913 2023-01-23 07:26:40 +09:00
Yukihiro "Matz" Matsumoto 4d5aadfc84 class.c (create_method_value): refactor mrb_method_t creation 2023-01-23 00:17:32 +09:00
Yukihiro "Matz" Matsumoto 079244c36a src/class.c: add new function mrb_vm_find_method
The function skips `cp` dereference, and improve performance of method
calls slightly.
2023-01-23 00:17:32 +09:00
Yukihiro "Matz" Matsumoto 6b0efd43da NEWS: copy entries from doc/mruby3.2.md 2023-01-23 00:17:32 +09:00
Yukihiro "Matz" Matsumoto 2e9f62b12c Merge pull request #5914 from dearblue/doc/mruby3.2.md
Update mruby3.2.md for changes behavior of `mrb_vm_run()`
2023-01-22 22:49:57 +09:00
Yukihiro "Matz" Matsumoto 3c02c517ca Merge pull request #5915 from dearblue/doc/mruby3.2.md.1
Update mruby3.2.md for new `mruby-data` gem
2023-01-22 22:49:05 +09:00
dearblue 998ef1711a Update mruby3.2.md for new mruby-data gem 2023-01-22 20:52:09 +09:00
dearblue a223778ee8 Update mruby3.2.md for changes behavior of mrb_vm_run() 2023-01-22 20:45:57 +09:00
Yukihiro "Matz" Matsumoto 882bb0662a Merge pull request #5912 from dearblue/io-popen
Replaced `NO_IO_POPEN` with `MRB_NO_IO_POPEN`
2023-01-22 13:37:39 +09:00
dearblue b0e537c05c Replaced NO_IO_POPEN with MRB_NO_IO_POPEN
ref. commit 9deb52c7b2
2023-01-22 09:20:10 +09:00
Yukihiro "Matz" Matsumoto 97fe582d41 Merge pull request #5911 from dearblue/eval+binding
Fixed `Kernel#.eval` crash when given a custom defined `Binding` instance
2023-01-20 22:44:28 +09:00
dearblue 36f822d9af Fixed Kernel#.eval crash when given a custom defined Binding instance
```console
% bin/mruby -e 'class Binding; end; eval "1", Binding.new'
zsh: segmentation fault (core dumped)  bin/mruby -e 'class Binding; end; eval "1", Binding.new'
```
2023-01-20 21:26:21 +09:00
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
19 changed files with 2158 additions and 1660 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.
+58 -6
View File
@@ -1,12 +1,64 @@
NEWS
----
This document is a list of user visible feature changes made between
releases except for bug fixes.
# User visible changes in `mruby3.2`
Note that each entry is kept so brief that no reason behind or
reference information is supplied with. For a full list of changes
with all sufficient information, see the ChangeLog file.
# The language
- Now `a::B = c` should evaluate `a` then `c`.
- Anonymous arguments `*`, `**`, `&` can be passed for forwarding.
- Multi-precision integer is available now via `mruby-bigint` gem.
** Information about first release v1.0.0
# mruby VM and bytecode
- `OP_ARYDUP` was renamed to `OP_ARYSPLAT`. The instruction name
was changed but instruction number and basic behavior have not
changed (except that `ARYDUP nil` makes `[]`).
# Tools
## `mruby`
- `-b` only specifies the script is the binary. The files loaded by `-r` are not affected by the option.
- `mruby` now loads complied binary if the suffix is `.mrb`.
## `mrbc`
- Add `--no-optimize` option to disable optimization.
# mrbgems
## mruby-class-ext
- Add `Class#subclasses` method.
- Add `Module#undefined_instance_methods` method.
## New bundled gems
- mruby-errno from [https://github.com/iij/mruby-errno.git]
- mruby-set from [https://github.com/yui-knk/mruby-set.git]
- mruby-dir from [https://github.com/iij/mruby-dir.git]
# CVEs
Following CVEs are fixed.
- [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-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631)
- [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-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631)
- [CVE-2022-0632](https://nvd.nist.gov/vuln/detail/CVE-2022-0632)
- [CVE-2022-0717](https://nvd.nist.gov/vuln/detail/CVE-2022-0717)
- [CVE-2022-0890](https://nvd.nist.gov/vuln/detail/CVE-2022-0890)
- [CVE-2022-1106](https://nvd.nist.gov/vuln/detail/CVE-2022-1106)
- [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)
- [CVE-2022-1934](https://nvd.nist.gov/vuln/detail/CVE-2022-1934)
+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-rc3.zip](https://github.com/mruby/mruby/archive/3.2.0-rc3.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
+19
View File
@@ -35,6 +35,25 @@
- mruby-errno from [https://github.com/iij/mruby-errno.git]
- mruby-set from [https://github.com/yui-knk/mruby-set.git]
- mruby-dir from [https://github.com/iij/mruby-dir.git]
- mruby-data
# Breaking Changes
## `mrb_vm_run()` may detach top-level local variables referenced from blocks
When the `mrb_vm_run()` function (including `mrb_top_run()`) is called,
the previous top-level local variables referenced from blocks is detached under either of the following conditions.
- If the `stack_keep` parameter is given as 0.
- If the number of variables in `irep` to be executed is less than the number of previous top-level local variables.
This change also affects API functions such as `mrb_load_string()` and `mrb_load_file()`.
The conditions under which the previous top-level local variables referenced from blocks is detached in these functions are as follows:
- If the function has no `mrbc_context` pointer parameter, or the `mrbc_context` pointer parameter is set to `NULL`.
- If the number of variables held in the `mrbc_context` pointer is less than the number of previous top-level local variables.
Intentional reliance on previous behavior may cause compatibility problems in your application.
# CVEs
+8
View File
@@ -22,6 +22,7 @@ mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
mrb_value mrb_mod_to_s(mrb_state *, mrb_value);
void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid);
mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
mrb_method_t mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid);
#endif
/* debug */
@@ -38,6 +39,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 +111,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 "RC3"
#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 23
/*
* 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
+2 -5
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)
{
@@ -32,14 +29,14 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
mrb_obj_class(mrb, binding));
}
scope_obj = mrb_iv_get(mrb, binding, MRB_SYM(proc));
mrb_assert(mrb_proc_p(scope_obj));
mrb_check_type(mrb, scope_obj, MRB_TT_PROC);
scope = mrb_proc_ptr(scope_obj);
if (MRB_PROC_CFUNC_P(scope)) {
e = NULL;
}
else {
mrb_value env = mrb_iv_get(mrb, binding, MRB_SYM(env));
mrb_assert(mrb_env_p(env));
mrb_check_type(mrb, env, MRB_TT_ENV);
e = (struct REnv *)mrb_obj_ptr(env);
mrb_assert(e != NULL);
}
+29 -32
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 MRB_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 MRB_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);
@@ -1706,10 +1714,10 @@ io_find_index(struct mrb_io *fptr, const char *rs, mrb_int rslen)
mrb_assert(rslen > 0);
const char c = rs[0];
const mrb_int limit = buf->len - rslen;
for (mrb_int i=buf->start; i<limit; i++) {
if (buf->mem[i] == c) {
if (memcmp(buf->mem+i, rs, rslen) == 0)
return i;
const char *p = buf->mem+buf->start;
for (mrb_int i=0; i<limit; i++) {
if (p[i] == c && (rslen == 1 || memcmp(p+i, rs, rslen) == 0)) {
return i;
}
}
return -1;
@@ -1775,36 +1783,25 @@ io_gets(mrb_state *mrb, mrb_value io)
outbuf = mrb_str_new(mrb, NULL, 0);
}
if (!rs_given) { /* no RS; only limit */
mrb_assert(limit_given);
for (;;) {
if (buf->len >= limit) {
for (;;) {
if (rs_given) { /* with RS */
int rslen = RSTRING_LEN(rs);
mrb_int idx = io_find_index(fptr, RSTRING_PTR(rs), rslen);
if (idx >= 0) { /* found */
mrb_int n = idx+rslen;
if (limit_given && limit < n) {
n = limit;
}
io_buf_cat(mrb, outbuf, fptr, n);
return outbuf;
}
}
if (limit_given) {
if (limit <= buf->len) {
io_buf_cat(mrb, outbuf, fptr, limit);
return outbuf;
}
io_buf_cat_all(mrb, outbuf, fptr);
io_buf_fill(mrb, fptr);
if (fptr->eof) {
if (RSTRING_LEN(outbuf) == 0) return mrb_nil_value();
return outbuf;
}
}
}
for (;;) { /* with RS */
int rslen = RSTRING_LEN(rs);
mrb_int idx = io_find_index(fptr, RSTRING_PTR(rs), rslen);
if (idx >= 0) { /* found */
mrb_int n = idx+rslen;
if (limit_given && limit < n) {
n = limit;
}
io_buf_cat(mrb, outbuf, fptr, n);
return outbuf;
}
if (limit_given && buf->len < limit) {
io_buf_cat(mrb, outbuf, fptr, limit);
return outbuf;
limit -= buf->len;
}
io_buf_cat_all(mrb, outbuf, fptr);
io_buf_fill(mrb, fptr);
+1
View File
@@ -369,6 +369,7 @@ assert('IO#gets') do
# gets with rs
io.pos = 0
assert_equal $mrbtest_io_msg[0, 6], io.gets(' '), "gets with rs"
assert_equal $mrbtest_io_msg[6, 3], io.gets(' '), "gets with rs(2)"
# gets with rs, limit
io.pos = 0
+27 -25
View File
@@ -244,6 +244,23 @@ mt_free(mrb_state *mrb, mt_tbl *t)
mrb_free(mrb, t);
}
static inline mrb_method_t
create_method_value(mrb_state *mrb, mrb_sym key, union mt_ptr val)
{
mrb_method_t m;
if (key & MT_FUNC_P) {
MRB_METHOD_FROM_FUNC(m, val.func);
}
else {
MRB_METHOD_FROM_PROC(m, val.proc);
}
if (key & MT_NOARG_P) {
MRB_METHOD_NOARG_SET(m);
}
return m;
}
MRB_API void
mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p)
{
@@ -259,19 +276,7 @@ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *
for (i=0; i<t->alloc; i++) {
mrb_sym key = keys[i];
if (MT_KEY_SYM(key)) {
mrb_method_t m;
if (key & MT_FUNC_P) {
MRB_METHOD_FROM_FUNC(m, vals[i].func);
}
else {
MRB_METHOD_FROM_PROC(m, vals[i].proc);
}
if (key & MT_NOARG_P) {
MRB_METHOD_NOARG_SET(m);
}
if (fn(mrb, MT_KEY_SYM(key), m, p) != 0)
if (fn(mrb, MT_KEY_SYM(key), create_method_value(mrb, key, vals[i]), p) != 0)
return;
}
}
@@ -1765,11 +1770,10 @@ mc_clear_by_id(mrb_state *mrb, mrb_sym id)
}
#endif
MRB_API mrb_method_t
mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
mrb_method_t
mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid)
{
mrb_method_t m;
struct RClass *c = *cp;
#ifndef MRB_NO_METHOD_CACHE
struct RClass *oc = c;
int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
@@ -1790,15 +1794,7 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
if (ret) {
if (ptr.proc == 0) break;
*cp = c;
if (ret & MT_FUNC_P) {
MRB_METHOD_FROM_FUNC(m, ptr.func);
}
else {
MRB_METHOD_FROM_PROC(m, ptr.proc);
}
if (ret & MT_NOARG_P) {
MRB_METHOD_NOARG_SET(m);
}
m = create_method_value(mrb, ret, ptr);
#ifndef MRB_NO_METHOD_CACHE
mc->c = oc;
mc->c0 = c;
@@ -1814,6 +1810,12 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
return m; /* no method */
}
MRB_API mrb_method_t
mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
{
return mrb_vm_find_method(mrb, *cp, cp, mid);
}
MRB_API mrb_method_t
mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
{
+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)
{
+22 -14
View File
@@ -562,7 +562,7 @@ prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, m
if (mid != missing) {
ci->u.target_class = mrb_class(mrb, recv);
}
m = mrb_method_search_vm(mrb, &ci->u.target_class, missing);
m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, missing);
if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */
mrb_stack_extend(mrb, 4);
@@ -662,7 +662,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, BLK_PTR(blk), 0, 0);
funcall_args_capture(mrb, 0, argc, argv, blk, ci);
ci->u.target_class = mrb_class(mrb, self);
m = mrb_method_search_vm(mrb, &ci->u.target_class, mid);
m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, mid);
if (MRB_METHOD_UNDEF_P(m)) {
m = prepare_missing(mrb, ci, self, mid, mrb_nil_value(), FALSE);
}
@@ -816,7 +816,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
}
c = mrb_class(mrb, self);
m = mrb_method_search_vm(mrb, &c, name);
m = mrb_vm_find_method(mrb, c, &c, name);
if (MRB_METHOD_UNDEF_P(m)) { /* call method_mising */
goto funcall;
}
@@ -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;
@@ -1762,7 +1769,7 @@ RETRY_TRY_BLOCK:
ci = cipush(mrb, a, CINFO_DIRECT, NULL, NULL, BLK_PTR(blk), 0, c);
recv = regs[0];
ci->u.target_class = (insn == OP_SUPER) ? CI_TARGET_CLASS(ci - 1)->super : mrb_class(mrb, recv);
m = mrb_method_search_vm(mrb, &ci->u.target_class, mid);
m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, mid);
if (MRB_METHOD_UNDEF_P(m)) {
m = prepare_missing(mrb, ci, recv, mid, blk, (insn == OP_SUPER));
}
@@ -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);