summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class.c1
-rw-r--r--src/gc.c4
-rw-r--r--src/kernel.c8
-rw-r--r--src/parse.y14
-rw-r--r--src/state.c2
-rw-r--r--src/symbol.c2
-rw-r--r--src/time.c37
-rw-r--r--src/variable.c11
-rw-r--r--src/vm.c17
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);
diff --git a/src/gc.c b/src/gc.c
index 3c00bb015..819fb94c6 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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
diff --git a/src/vm.c b/src/vm.c
index bd3d05d81..62ef5069d 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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;
}