summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
AgeCommit message (Collapse)Author
2016-11-24Fix segfault when defining class inside instance_exec on primitiveBouke van der Bijl
2016-11-07fixed wrong stack adjustment for ensure clauses; fix #3175Yukihiro "Matz" Matsumoto
2016-11-05associate REnv to the executing block; fix #3214Yukihiro "Matz" Matsumoto
2016-10-20Move to_proc conversion from OP_ENTER to OP_SENDB; fix #3227Yukihiro "Matz" Matsumoto
2016-09-20Fix return value type of bytecode_decoderKazuaki Tanaka
2016-09-20Bytecode decoder support, MRB_BYTECODE_DECODE_OPTIONKazuaki Tanaka
2016-09-06surpress warning when MRB_DISABLE_STDIOyuri
2016-09-05Should clear method nameksss
- Fix method name in top-level - Fix SEGV when call Exception#backtrace if callinfo over CALLINFO_INIT_SIZE(32)
2016-07-14Should raise LocalJumpError when no block givenksss
2016-05-10use mrb_int_mul_overflow()cremno
2016-05-09Remove needless assignmentKouhei Sutou
d4ee409ae912dec6eb719a5727da4566f817d9d8 should remove this line.
2016-04-27Use stack directlyKenji Okimoto
See https://github.com/mruby/mruby/pull/3142#issuecomment-201138873
2016-04-11vm.c: mrb_hash_set() may reallocate VM stack; close #3133Yukihiro "Matz" Matsumoto
2016-03-25Add missing regs updateKouhei Sutou
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-01-19Fix SEGV on re-raising NoMemoryErrorKouhei Sutou
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-07change mrb_run related API names; compatibility macros providedYukihiro "Matz" Matsumoto
2016-01-04stack_extend before eval_under()Yukihiro "Matz" Matsumoto
2016-01-02instance_eval should pass the receiver as a block parameter; close #3029Yukihiro "Matz" Matsumoto
2016-01-02mruby-fiber: fiber_switch() to use nesting VM when it's called from C API or ↵Yukihiro "Matz" Matsumoto
mrb_funcall(); close #3056
2015-12-31GC must scan env from fibers even when it's not yet copied to heap; fix #3063Yukihiro "Matz" Matsumoto
2015-12-29Support backtrace after method callsKouhei Sutou
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-11-27include changed from by quotes ("") to by brackets (<>); close #3032Yukihiro "Matz" Matsumoto
2015-11-17DISABLE_STDIO/ENABLE_DEBUG macros to rename; close #3014Yukihiro "Matz" Matsumoto
changes: * rename DISABLE_STDIO -> MRB_DISABLE_STDIO * rename ENABLE_DEBUG -> MRB_ENABLE_DEBUG_HOOK * no more opposite macro definitions (e.g. ENABLE_STDIO, DISABLE_DEBUG). * rewrite above macro references throughout the code. * update documents
2015-11-07PR #2521 did not work for singleton classes for non-class objects; fix #3003Yukihiro "Matz" Matsumoto
2015-10-27mrb_str_concat() may call VM resursively thus may reallocate VM stack; close ↵Yukihiro "Matz" Matsumoto
#3000
2015-10-19Clean up GC codefurunkel
2015-09-02ensure must not be called before rescue; fix #2933Yukihiro "Matz" Matsumoto
2015-08-10prevent out-of-bounds ensure clause access; fix #2910Yukihiro "Matz" Matsumoto
2015-07-30vm: execute ensure without exception at the top of the fiber; fix #2904Yukihiro "Matz" Matsumoto
2015-07-30vm: execute ensure at the top of the fiber; fix #2903Yukihiro "Matz" Matsumoto
2015-07-13refactor mrb_bob_missing to share raising NoMethodError code; fix #2878Yukihiro "Matz" Matsumoto
Note: arguments of mrb_no_method_error() has changed. You need to replace 3rd and 4th argument (say n, argv) to mrb_ary_new_from_values(mrb, n, argv).
2015-07-07method_missing definition may be undefined; fix #2878Yukihiro "Matz" Matsumoto
2015-05-31fix OP_APOST bug for no pre arg cases; fix #2810Yukihiro "Matz" Matsumoto
2015-05-25Move "src/mrb_throw.h" to "include/mruby/throw.h".take_cheeze
Related to #2760.
2015-05-15remove mrb_define_method_vm() functioncremno
It isn't needed as it's very similar to mrb_define_method_raw() and also there's only one place where mrb_proc_ptr() actually has to be called. Inspired by @furunkel's method cache patch (#2764).
2015-04-27C++ compilation failed due to skipping iniitalization by goto out_superYukihiro "Matz" Matsumoto
2015-04-27super should not be called outside of a method; fix #2770Yukihiro "Matz" Matsumoto
2015-03-21execute ensure clause only when skipping call frame; fix #2726Yukihiro "Matz" Matsumoto
2015-03-05stack_extend in mrb_f_sendGo Saito
mrb_f_send needs stack_extend like OP_SEND Signed-off-by: Go Saito <[email protected]>
2015-02-28Use ptrdiff_t to suppress signedness warningKouhei Sutou
3df32161797aa9c6e9df259e8d8571b454cb2333 says so but there is no warning with GCC 4.9 on my Debian GNU/Linux environment.
2015-02-27Merge pull request #2736 from cremno/delete-prototypes-of-undefined-functionsYukihiro "Matz" Matsumoto
delete prototypes of undefined functions
2015-02-27change size_t to ptrdiff_t to silence signedness warnings; #2732Yukihiro "Matz" Matsumoto
2015-02-26delete prototypes of undefined functionscremno
2015-02-25Fix a crash bug on raising after reallocKouhei Sutou
The following program reproduces this problem: #include <mruby.h> static mrb_value recursive(mrb_state *mrb, mrb_value self) { mrb_int n; mrb_get_args(mrb, "i", &n); if (n == 0) { mrb_raise(mrb, E_RUNTIME_ERROR, "XXX"); } else { mrb_funcall(mrb, self, "recursive", 1, mrb_fixnum_value(n - 1)); } return self; } int main(void) { mrb_state *mrb; mrb = mrb_open(); mrb_define_method(mrb, mrb->kernel_module, "recursive", recursive, MRB_ARGS_REQ(1)); mrb_funcall(mrb, mrb_top_self(mrb), "recursive", 1, mrb_fixnum_value(30)); mrb_close(mrb); } Recursive method call isn't required. It's just for expanding call info stack. If mrb_realloc() is called in cipush(), cibase address is changed. So, we shouldn't compare ci before mrb_realloc() and cibase after mrb_realloc(). It accesses unknown address and causes crash.
2015-02-23fix pointer dereference after reallocGo Saito
In src/vm.c: mrb_funcall_with_block stack_extend may realloc mrb->c->stbase, if argv points on mruby's stack, then it points invalid address after stack_extend. e.g. src/class.c: mrb_instance_new This code: ```ruby class A def initialize(a0,a1,a2,a3,a4) a0.is_a? Array end end def f(a0,a1,a2,a3,a4) A.new(a0,a1,a2,a3,a4) f(a0,a1,a2,a3,a4) end f(0,1,2,3,4) ``` is expected to get exception ``` stack level too deep. (limit=(0x40000 - 128)) (SystemStackError) ``` but get segfault. Signed-off-by: Go Saito <[email protected]>
2015-02-05Fix ensure with yield context on break and returnKouhei Sutou
How to reproduce: class A def x yield ensure y end def y end end # Work A.new.x do end # Not work # trace: # [2] /tmp/a.rb:5:in A.x # [0] /tmp/a.rb:15 # /tmp/a.rb:5: undefined method 'y' for main (NoMethodError) A.new.x do break end # trace: # [2] /tmp/a.rb:5:in A.call # [0] /tmp/a.rb:19 # /tmp/a.rb:5: undefined method 'y' for main (NoMethodError) lambda do A.new.x do return end end.call `self` in ensure is broken when yield and break/return are used.
2015-01-26Use setter macro instead of directly setting valuesXuejie "Rafael" Xiao
2014-11-28preserve ICLASS in ci->target_class; fix #2657; ensuring #1467 #1470 #1493 ↵Yukihiro "Matz" Matsumoto
still works
2014-11-19Fix an error when calling a method implemented in C by super() with ↵sdottaka
arguments. This fix makes the following code workable: Expected: class MRBTime < Time; def self.new; super(2012, 4, 21); end; end MRBTime.new # => Sat Apr 21 00:00:00 2012 Actual: class MRBTime < Time; def self.new; super(2012, 4, 21); end; end MRBTime.new # => can't convert nil into Integer (TypeError)
2014-10-15fix typo (i->idx)Jan Berdajs