diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class.c | 1 | ||||
| -rw-r--r-- | src/gc.c | 4 | ||||
| -rw-r--r-- | src/kernel.c | 8 | ||||
| -rw-r--r-- | src/parse.y | 14 | ||||
| -rw-r--r-- | src/state.c | 2 | ||||
| -rw-r--r-- | src/symbol.c | 2 | ||||
| -rw-r--r-- | src/time.c | 37 | ||||
| -rw-r--r-- | src/variable.c | 11 | ||||
| -rw-r--r-- | src/vm.c | 17 |
9 files changed, 62 insertions, 34 deletions
diff --git a/src/class.c b/src/class.c index 38eb5ea1f..b8532cdcc 100644 --- a/src/class.c +++ b/src/class.c @@ -115,7 +115,6 @@ mrb_define_module_id(mrb_state *mrb, mrb_sym name) { struct RClass *m = mrb_module_new(mrb); - m->mt = kh_init(mt, mrb); mrb_obj_iv_set(mrb, (struct RObject*)mrb->object_class, name, mrb_obj_value(m)); mrb_name_class(mrb, m, name); @@ -17,6 +17,10 @@ #include "mruby/data.h" #include "mruby/variable.h" +#ifndef SIZE_MAX +#include <limits.h> // for SIZE_MAX +#endif + /* = Tri-color Incremental Garbage Collection diff --git a/src/kernel.c b/src/kernel.c index f5a1f3d53..468891b23 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -555,6 +555,8 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self) return self; } +mrb_value mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c); + /* 15.3.1.3.18 */ /* * call-seq: @@ -580,11 +582,13 @@ mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) { mrb_value a, b; + mrb_value cv; if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { - mrb_raise(mrb, E_RUNTIME_ERROR, "instance_eval with string not implemented"); + mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented"); } - return mrb_yield_with_self(mrb, b, 0, 0, self); + cv = mrb_singleton_class(mrb, self); + return mrb_yield_internal(mrb, b, 0, 0, self, mrb_class_ptr(cv)); } int diff --git a/src/parse.y b/src/parse.y index 87962b4bb..a2a12b14d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -4871,25 +4871,27 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) n = snprintf(buf, sizeof(buf), "line %d: %s\n", p->error_buffer[0].lineno, p->error_buffer[0].message); mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n)); + mrb_parser_free(p); + return mrb_undef_value(); } else { - mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, "", 0)); + mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, "syntax error", 0)); + mrb_parser_free(p); + return mrb_nil_value(); } - mrb_parser_free(p); - return mrb_undef_value(); } n = mrb_generate_code(mrb, p->tree); mrb_parser_free(p); if (n < 0) { - mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SCRIPT_ERROR, "", 0)); - return mrb_undef_value(); + mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SCRIPT_ERROR, "codegen error", 0)); + return mrb_nil_value(); } if (c) { if (c->dump_result) codedump_all(mrb, n); if (c->no_exec) return mrb_fixnum_value(n); } v = mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); - if (mrb->exc) return mrb_undef_value(); + if (mrb->exc) return mrb_nil_value(); return v; } diff --git a/src/state.c b/src/state.c index 7f74606ff..0d236e660 100644 --- a/src/state.c +++ b/src/state.c @@ -83,7 +83,7 @@ mrb_add_irep(mrb_state *mrb, int idx) while (mrb->irep_capa <= idx) { mrb->irep_capa *= 2; } - mrb->irep = mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep)*mrb->irep_capa); + mrb->irep = mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep*)*mrb->irep_capa); } } diff --git a/src/symbol.c b/src/symbol.c index 40484d4b5..6e92fb6c7 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -339,7 +339,7 @@ sym_inspect(mrb_state *mrb, mrb_value sym) memcpy(RSTRING(str)->ptr+1, name, len); if (!symname_p(name) || strlen(name) != len) { str = mrb_str_dump(mrb, str); - strncpy(RSTRING(str)->ptr, ":\"", 2); + memcpy(RSTRING(str)->ptr, ":\"", 2); } return str; } diff --git a/src/time.c b/src/time.c index 45e796069..c988d0fd0 100644 --- a/src/time.c +++ b/src/time.c @@ -160,13 +160,21 @@ mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm) /* Allocates a mrb_time object and initializes it. */ static struct mrb_time* -mrb_time_alloc(mrb_state *mrb, mrb_float seconds, enum mrb_timezone timezone) +mrb_time_alloc(mrb_state *mrb, mrb_float sec, mrb_float usec, enum mrb_timezone timezone) { struct mrb_time *tm; tm = mrb_malloc(mrb, sizeof(struct mrb_time)); - tm->sec = (time_t)seconds; - tm->usec = (seconds - tm->sec) * 1.0e6; + tm->sec = (time_t)sec; + tm->usec = (sec - tm->sec) * 1.0e6 + usec; + while (tm->usec < 0) { + tm->sec--; + tm->usec += 1.0e6; + } + while (tm->usec > 1.0e6) { + tm->sec++; + tm->usec -= 1.0e6; + } tm->timezone = timezone; mrb_time_update_datetime(tm); @@ -174,9 +182,9 @@ mrb_time_alloc(mrb_state *mrb, mrb_float seconds, enum mrb_timezone timezone) } static mrb_value -mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_float seconds, enum mrb_timezone timezone) +mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_float sec, mrb_float usec, enum mrb_timezone timezone) { - return mrb_time_wrap(mrb, c, mrb_time_alloc(mrb, seconds, timezone)); + return mrb_time_wrap(mrb, c, mrb_time_alloc(mrb, sec, usec, timezone)); } static struct mrb_time* @@ -227,10 +235,10 @@ mrb_time_now(mrb_state *mrb, mrb_value self) static mrb_value mrb_time_at(mrb_state *mrb, mrb_value self) { - mrb_float f; + mrb_float f, f2 = 0; - mrb_get_args(mrb, "f", &f); - return mrb_time_make(mrb, mrb_class_ptr(self), f, MRB_TIMEZONE_LOCAL); + mrb_get_args(mrb, "f|f", &f, &f2); + return mrb_time_make(mrb, mrb_class_ptr(self), f, f2, MRB_TIMEZONE_LOCAL); } static struct mrb_time* @@ -258,7 +266,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time."); } - return mrb_time_alloc(mrb, nowsecs+ausec/10e6, timezone); + return mrb_time_alloc(mrb, nowsecs, ausec, timezone); } /* 15.2.19.6.2 */ @@ -340,9 +348,7 @@ mrb_time_plus(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "f", &f); tm = mrb_get_datatype(mrb, self, &mrb_time_type); if (!tm) return mrb_nil_value(); - f += tm->sec; - f += (mrb_float)tm->usec / 1.0e6; - return mrb_time_make(mrb, mrb_obj_class(mrb, self), f, tm->timezone); + return mrb_time_make(mrb, mrb_obj_class(mrb, self), tm->sec+f, tm->usec, tm->timezone); } static mrb_value @@ -363,11 +369,8 @@ mrb_time_minus(mrb_state *mrb, mrb_value self) return mrb_float_value(f); } else { - mrb_float f, f2; - mrb_get_args(mrb, "f", &f2); - - f = ((mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); - return mrb_time_make(mrb, mrb_obj_class(mrb, self), f-f2, tm->timezone); + mrb_get_args(mrb, "f", &f); + return mrb_time_make(mrb, mrb_obj_class(mrb, self), tm->sec-f, tm->usec, tm->timezone); } } diff --git a/src/variable.c b/src/variable.c index 501bed5a6..a1a7f2e82 100644 --- a/src/variable.c +++ b/src/variable.c @@ -10,6 +10,7 @@ #include "mruby/variable.h" #include "error.h" #include "mruby/array.h" +#include "mruby/proc.h" #ifdef ENABLE_REGEXP #include "re.h" @@ -342,7 +343,10 @@ mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) mrb_value mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) { - return const_get(mrb, mrb->ci->target_class, sym); + struct RClass *c = mrb->ci->proc->target_class; + + if (!c) c = mrb->ci->target_class; + return const_get(mrb, c, sym); } void @@ -355,7 +359,10 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) void mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) { - mrb_obj_iv_set(mrb, (struct RObject*)mrb->ci->target_class, sym, v); + struct RClass *c = mrb->ci->proc->target_class; + + if (!c) c = mrb->ci->target_class; + mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v); } void @@ -237,7 +237,7 @@ mrb_funcall_argv(mrb_state *mrb, mrb_value self, const char *name, int argc, mrb } mrb_value -mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self) +mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c) { struct RProc *p; mrb_sym mid = mrb->ci->mid; @@ -251,7 +251,7 @@ mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_ ci->proc = p; ci->stackidx = mrb->stack - mrb->stbase; ci->argc = argc; - ci->target_class = p->target_class; + ci->target_class = c; ci->nregs = argc + 2; ci->acc = -1; mrb->stack = mrb->stack + n; @@ -277,13 +277,17 @@ mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_ mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv) { - return mrb_yield_with_self(mrb, b, argc, argv, mrb->stack[0]); + struct RProc *p = mrb_proc_ptr(b); + + return mrb_yield_internal(mrb, b, argc, argv, mrb->stack[0], p->target_class); } mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value v) { - return mrb_yield_with_self(mrb, b, 1, &v, mrb->stack[0]); + struct RProc *p = mrb_proc_ptr(b); + + return mrb_yield_internal(mrb, b, 1, &v, mrb->stack[0], p->target_class); } static void @@ -1564,6 +1568,11 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_TCLASS) { /* A B R(A) := target_class */ + if (!mrb->ci->target_class) { + mrb_value exc = mrb_exc_new(mrb, E_TYPE_ERROR, "no target class or module", 25); + mrb->exc = (struct RObject*)mrb_object(exc); + goto L_RAISE; + } regs[GETARG_A(i)] = mrb_obj_value(mrb->ci->target_class); NEXT; } |
