Commit Graph

3136 Commits

Author SHA1 Message Date
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
Yukihiro "Matz" Matsumoto f7afe1d82a change mrb_run related API names; compatibility macros provided 2016-01-07 22:36:29 +09:00
Yukihiro "Matz" Matsumoto 725b3ca5a7 move KHASH_DECLARE(ht..) to mruby/hash.h; close #3073 2016-01-07 12:46:38 +09:00
Syohei YOSHIDA 931cc0359a printf precision parameter must be 'int' type
There is a problem when MRB_INT64 is enabled.
2016-01-07 11:06:20 +09:00
ksss af21b365d2 symname_p support !~ 2016-01-06 11:59:09 +09:00
Yukihiro "Matz" Matsumoto 9145aed85e bytes2chars() conversion to fail if target byte offset is not on the character boundary; ref #3067
that means String#index matches first byte of a multi-byte character. this behavior is different
from CRuby, but a compromise for mruby which does not have encoding stuffs.
2016-01-05 18:05:25 +09:00
Yukihiro "Matz" Matsumoto aec825a64c stack_extend before eval_under() 2016-01-04 10:22:38 +09:00
Yukihiro "Matz" Matsumoto aa1f668b80 instance_eval should pass the receiver as a block parameter; close #3029 2016-01-02 22:01:00 +09:00
Yukihiro "Matz" Matsumoto bd462c5edc mruby-fiber: fiber_switch() to use nesting VM when it's called from C API or mrb_funcall(); close #3056 2016-01-02 13:48:45 +09:00
Yukihiro "Matz" Matsumoto 31b8469bff Merge pull request #3067 from ksss/use-memchr
Use memchr for performance
2015-12-31 21:20:51 +09:00
ksss 6c1b6ef7a5 Use memchr for performance
```ruby
s = "b"
str = ("a" * 100 + s)

t = Time.now
str.index(s)
puts Time.now - t
```

before => 0.000788
after  => 0.000508

---

```ruby
s = "b"
str = ("a" * 100 * 1024 * 1024 + s)

t = Time.now
str.index(s)
puts Time.now - t
```

before => 0.225474
after  => 0.008658
2015-12-31 17:52:22 +09:00
Yukihiro "Matz" Matsumoto 3531fe179c GC must scan env from fibers even when it's not yet copied to heap; fix #3063 2015-12-31 00:11:37 +09:00
Kouhei Sutou a561bdb25f Support backtrace after method calls
GitHub: fix #2902, #2917

The current implementation traverses stack to retrieve backtrace. But
stack will be changed when some operations are occurred. It means that
backtrace may be broken after some operations.

This change (1) saves the minimum information to retrieve backtrace when
exception is raised and (2) restores backtrace from the minimum
information when backtrace is needed. It reduces overhead for creating
backtrace Ruby objects.

The space for the minimum information is reused by multiple
exceptions. So memory allocation isn't occurred for each exception.
2015-12-29 20:36:12 +09:00
Kouhei Sutou 1eeeecb08a Fix indent 2015-12-29 14:20:10 +09:00
Yasuhiro Matsumoto 7cc33af2dc fix build on VS2012 2015-12-22 17:46:20 +09:00
Kei Sawada d69b5c3fc7 Add case statement of MRB_TT_SCLASS in mrb_obj_is_kind_of() 2015-12-16 15:54:03 +09:00
Yukihiro "Matz" Matsumoto f54a98ff15 mrb_str_len_to_inum(): fixed a bug with MRB_INT_MIN conversion; fix #3048 2015-12-16 14:49:43 +09:00
Yukihiro "Matz" Matsumoto d18c55fca7 mrb_str_len_to_inum(): fixed a bug with underscores in digits; fix #3049 2015-12-16 14:49:08 +09:00