Commit Graph

3153 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 6c299aae67 fixed wrong stack adjustment for ensure clauses; fix #3175 2016-11-07 00:44:08 +09:00
Yukihiro "Matz" Matsumoto 0b8d8dd379 associate REnv to the executing block; fix #3214 2016-11-05 02:52:34 +09:00
Yukihiro "Matz" Matsumoto 9a126278b6 should not unshare() reclaimed env objects; fix #3230 2016-10-28 09:21:14 +09:00
Yukihiro "Matz" Matsumoto c45ed46f28 macro mrb_bool() may evaluate arg multiple times; ref #3228 2016-10-24 01:30:31 +09:00
Yukihiro "Matz" Matsumoto 7061658b5b Merge pull request #3228 from ksss/respond_to_missing
Kernel#respond_to? should return true|false only
2016-10-24 01:27:13 +09:00
ksss 022e147b78 Kernel#respond_to? should return true|false only 2016-10-23 18:25:47 +09:00
Yukihiro "Matz" Matsumoto 6fd0e601cf Move to_proc conversion from OP_ENTER to OP_SENDB; fix #3227 2016-10-20 23:49:40 +09:00
Nobuyoshi Nakada 6511bfd79a Removed trailing spaces 2016-09-28 12:29:41 +09:00
Yukihiro "Matz" Matsumoto afbe211c60 mrb_str_strlen() should be MRB_API; ref #3216 2016-09-27 10:29:56 +09:00
Kouhei Sutou 91bd3ebd32 Remove needless MRB_API
ref #3215

If a function (such as mrb_read_irep_file()) is declared without MRB_API
in header file (such as include/mruby/dump.h), implementation of the
function in source file (such as src/load.c) should also defined without
MRB_API.

If MRB_API is mismatch, Visual C++ reports link error with C2375 error
code: https://msdn.microsoft.com/en-us/library/5k6kw95a.aspx
2016-09-25 21:47:49 +09:00
Yukihiro "Matz" Matsumoto 7a382e8bdf Remove unnecessary MRB_API from read_irep related functions; ref #3215 2016-09-24 05:26:51 +09:00
Kazuaki Tanaka cb29c9b415 Fix return value type of bytecode_decoder 2016-09-20 23:15:49 +00:00
Kazuaki Tanaka 968ebac001 Bytecode decoder support, MRB_BYTECODE_DECODE_OPTION 2016-09-20 23:07:28 +00:00
ksss d265c03da0 Fix SEGV when splat object
Splat operation should return an array.
And raise an error if result of convert by to_a is not array or nil.
2016-09-08 16:35:17 +09:00
yuri c9d4d96872 surpress warning when MRB_DISABLE_STDIO 2016-09-06 22:41:50 +09:00
ksss a5c2e95b10 Should clear method name
- Fix method name in top-level
- Fix SEGV when call Exception#backtrace if callinfo over CALLINFO_INIT_SIZE(32)
2016-09-05 21:58:08 +09:00
Yukihiro "Matz" Matsumoto ff3e4b91f2 Move Module#include and #prepend to class.c; ref #3197
To avoid VM nesting with mrb_funcall()
2016-08-20 00:03:30 +09:00
William Light e02a88e031 make mrb_hash_values() a public API function 2016-08-01 11:05:46 +02:00
ksss 9dc820590f Should raise LocalJumpError when no block given 2016-07-14 13:03:25 +09:00
Yuji Yamano 00faf3d317 Fix compilation error with GC_PROFILE. 2016-06-29 03:57:02 -04:00
Yasuhiro Matsumoto 8764bd282c fix public_methods(false) 2016-06-18 01:18:24 +09:00
Yukihiro "Matz" Matsumoto 09b11850a5 mrb_gc_unregister() to remove one registration; close #3160
when multiple mrb_gc_register() were called for the same object
2016-06-10 10:12:48 +09:00
Yukihiro "Matz" Matsumoto 8dde647a51 add temporary workaround for irep memory corruption
need to find out real memory bug that appears in full-debug/mrbtest
2016-06-10 10:04:52 +09:00
cremno 7453a5dfea use mrb_int_mul_overflow() 2016-05-10 19:12:02 +02:00
cremno bf63cff46e fix MRUBY_VERSION value
RUBY_ENGINE_VERSION and MRUBY_VERSION should refer to the same string.
2016-05-09 17:19:47 +02:00
Kouhei Sutou 51cc35dc09 Remove needless assignment
d4ee409ae9 should remove this line.
2016-05-09 14:05:51 +09:00
Kenji Okimoto d4ee409ae9 Use stack directly
See https://github.com/mruby/mruby/pull/3142#issuecomment-201138873
2016-04-27 10:18:13 +09:00
Yukihiro "Matz" Matsumoto ae5b5ce575 vm.c: mrb_hash_set() may reallocate VM stack; close #3133 2016-04-11 14:11:44 +09:00
Kouhei Sutou c69cba2ad9 Add missing regs update
mrb_vm_define_class() may realloc() mrb->c->stack because it calls
mrb_funcall() for inherited hook. If mrb->c->stack is realloc()-ed, regs
refers orphan address.
2016-03-25 00:25:48 +09:00
Yukihiro "Matz" Matsumoto 0c28c7d754 change backtrace sep from const char* to char 2016-03-07 10:59:34 +09:00
Kouhei Sutou f1eb3aea11 Fix segmentation fault by backtrace and GC
GitHub: fix #3122

It reverts #3126. #3126 fixes the segmentation fault but generates
broken backtrace.

This change fixes the segmentation fault and generates correct
backtrace. The strategy of this change is "generating backtrace while
irep is alive".

/tmp/test.rb:
    def gen
      e0 = nil
      begin
        1.times {
          raise 'foobar'
        }
      rescue => e
        e0 = e
      end
      e0
    end

    e = gen
    GC.start
    gen
    GC.start

    puts e.backtrace.join("\n")

Run:

    % bin/mruby /tmp/test.rb
    /tmp/test.rb:5:in Object.gen
    /home/kou/work/ruby/mruby.kou/mrblib/numeric.rb:77:in Integral#times
    /tmp/test.rb:4:in Object.gen
    /tmp/test.rb:13

FYI:

    % ruby -v /tmp/test.rb
    ruby 2.3.0p0 (2015-12-25) [x86_64-linux-gnu]
    /tmp/test.rb:5:in `block in gen'
    /tmp/test.rb:4:in `times'
    /tmp/test.rb:4:in `gen'
    /tmp/test.rb:13:in `<main>'
2016-03-06 11:58:54 +09:00
Kouhei Sutou d77c72dac5 Revert "Merge pull request #3126 from jbreeden/backtrace_irep_null_check"
This reverts commit bf7719fe8d, reversing
changes made to 4f4fa0ade0.

We should get backtrace while irep is alive.
2016-03-06 11:51:04 +09:00
jbreeden d2a8f7e0cc Fix Travis CI 2016-03-05 14:22:31 -08:00
jbreeden e02ff850fe Null check for irep & initialize loc.lineno 2016-03-05 13:45:56 -08:00
Carlo Prelz d6cbe1bfc6 The original code crashed when mrb->backtrace.n grew to 16.
It looks like the logic to reallocate the backtrace was flawed,
based on the wrong variable (loc_raw->i, which, as I have verified,
decreases from 16 to 0 instead of increasing)

I am not sure if this is the correct fix
2016-02-26 09:21:33 +01:00
Malizia R 52aba8a706 Avoid Error when Compiling with -std=c99 flag 2016-02-24 16:39:38 -03:00
Yukihiro "Matz" Matsumoto 81acbd2dd1 cosmetic change for OP_EQ 2016-02-22 09:38:20 +09:00
Yukihiro "Matz" Matsumoto ec35e549ad need to free context when reclaiming fiber object in GC; fix #3109 2016-02-17 10:19:14 +09:00
Yukihiro "Matz" Matsumoto 62b06ab4d4 [cppcheck] mrb_str_rindex() remove unnecessary len update by chars2bytes() 2016-02-05 21:54:07 +09:00
Yukihiro "Matz" Matsumoto af4dd3d579 [cppcheck] remove duplicated break 2016-02-05 21:48:44 +09:00
Yukihiro "Matz" Matsumoto 3c73c315f4 Hash: check flags before accessing ifnone; ref #980 2016-02-05 10:08:28 +09:00
Yukihiro "Matz" Matsumoto 25e4ec3f37 cache UTF8 status for utf8_strlen(); ref #980 2016-02-04 23:33:16 +09:00
Yukihiro "Matz" Matsumoto 5e514c910f cache mrb_regexp_p(); ref #980 2016-02-04 23:22:01 +09:00
Kouhei Sutou c77123d20a Fix SEGV by stack extension in mrb_get_args()
mrb_get_args() keeps pointer of the current stack. But address of the
current stack maybe changed by method call.

'i' format character calls #to_i when the argument isn't integer but
has #to_i.

Here is a code that may call #to_i in mrb_get_args():

    case 'i':
      // ...
            default:
              *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
              break;
     // ...

Here is a code #to_i is called:

    class X
      def initialize(i)
        @i = i
      end

      def to_i
        @i
      end
    end

    [][X.new(0), 0] # X#to_i is called

So, mrb_get_args() shouldn't keep pointer and use it. mrb_get_args()
should always refer mrb->ci->stack to use valid address of the current
stack.
2016-01-22 00:20:00 +09:00
Kouhei Sutou 1d84b3205a Fix SEGV on re-raising NoMemoryError
Think about the following Ruby script:

segv.rb:

    begin
      lambda do
        lambda do
          "x" * 1000 # NoMemoryError
        end.call
      end.call
    rescue
      raise
    end

If memory can't allocate after `"x" * 1000`, mruby crashes.

Because L_RAISE: block in mrb_vm_exec() calls mrb_env_unshare() via
cipop() and mrb_env_unshare() uses allocated memory without NULL check:

L_RAISE: block:

    L_RAISE:
      // ...
      while (ci[0].ridx == ci[-1].ridx) {
        cipop(mrb);
        // ...
      }

cipop():

    static void
    cipop(mrb_state *mrb)
    {
      struct mrb_context *c = mrb->c;

      if (c->ci->env) {
        mrb_env_unshare(mrb, c->ci->env);
      }

      c->ci--;
    }

mrb_env_unshare():

    MRB_API void
    mrb_env_unshare(mrb_state *mrb, struct REnv *e)
    {
      size_t len = (size_t)MRB_ENV_STACK_LEN(e);
      // p is NULL in this case
      mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);

      MRB_ENV_UNSHARE_STACK(e);
      if (len > 0) {
        stack_copy(p, e->stack, len); // p is NULL but used. It causes SEGV.
      }
      e->stack = p;
      mrb_write_barrier(mrb, (struct RBasic *)e);
    }

To solve the SEGV, this change always raises NoMemoryError even when
realloc() is failed after the first NoMemoryError in
mrb_realloc(). mrb_unv_unshare() doesn't need to check NULL with this
change.

But it causes infinite loop in the following while:

    L_RAISE:
      // ...
      while (ci[0].ridx == ci[-1].ridx) {
        cipop(mrb);
        // ...
      }

Because cipop() never pops ci.

This change includes cipop() change. The change pops ci even when
mrb_unv_unshare() is failed by NoMemoryError.

This case can be reproduced by the following program:

    #include <stdlib.h>
    #include <mruby.h>
    #include <mruby/compile.h>

    static void *
    allocf(mrb_state *mrb, void *ptr, size_t size, void *ud)
    {
      static mrb_bool always_fail = FALSE;

      if (size == 1001) {
        always_fail = TRUE;
      }
      if (always_fail) {
        return NULL;
      }

      if (size == 0) {
        free(ptr);
        return NULL;
      } else {
        return realloc(ptr, size);
      }
    }

    int
    main(int argc, char **argv)
    {
      mrb_state *mrb;
      mrbc_context *c;
      FILE *file;

      mrb = mrb_open_allocf(allocf, NULL);
      c = mrbc_context_new(mrb);
      file = fopen(argv[1], "r");
      mrb_load_file_cxt(mrb, file, c);
      fclose(file);
      mrbc_context_free(mrb, c);
      mrb_close(mrb);

      return EXIT_SUCCESS;
    }

Try the following command lines:

    % cc -I include -L build/host/lib -O0 -g3 -o no-memory no-memory.c -lmruby -lm
    % ./no-memory segv.rb
2016-01-19 16:37:42 +09:00
Syohei YOSHIDA 787685a0b9 Fix all zero string case 2016-01-14 11:07:07 +09:00
Yukihiro "Matz" Matsumoto 8143285956 Merge pull request #3080 from kou/fix-class-variable-in-module
Fix class variable reference in module
2016-01-11 10:00:34 +09:00
Kouhei Sutou ad492eb9f3 Fix class variable reference in module
Fix #3079
2016-01-11 00:34:15 +09:00
Simon Génier 146a9eeb38 Fix segfault on mrb_exc_backtrace.
The code to iterate over backtrace locations was changed in #3065, but
unfortunately output_backtrace was not correctly updated to forward the
callback.
2016-01-07 11:24:16 -05:00
Yukihiro "Matz" Matsumoto f3cce24035 replace mrb_toplevel_run() by mrb_top_run() 2016-01-07 22:48:22 +09:00