summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class.c6
-rw-r--r--src/error.c16
-rw-r--r--src/state.c6
-rw-r--r--src/vm.c25
4 files changed, 42 insertions, 11 deletions
diff --git a/src/class.c b/src/class.c
index 0ba702919..a00000375 100644
--- a/src/class.c
+++ b/src/class.c
@@ -203,6 +203,12 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
return c;
}
+int
+mrb_class_defined(mrb_state *mrb, const char *name)
+{
+ return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_intern(mrb, name));
+}
+
static struct RClass *
class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
{
diff --git a/src/error.c b/src/error.c
index 421321c3d..6bd891768 100644
--- a/src/error.c
+++ b/src/error.c
@@ -5,6 +5,7 @@
*/
#include "mruby.h"
+#include <errno.h>
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
@@ -401,7 +402,20 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv)
void
mrb_sys_fail(mrb_state *mrb, const char *mesg)
{
- mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ struct RClass *sce;
+ mrb_int no;
+
+ no = (mrb_int)errno;
+ if (mrb_class_defined(mrb, "SystemCallError")) {
+ sce = mrb_class_get(mrb, "SystemCallError");
+ if (mesg != NULL) {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
+ } else {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
+ }
+ } else {
+ mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ }
}
void
diff --git a/src/state.c b/src/state.c
index b6805a4a4..efb6d66b1 100644
--- a/src/state.c
+++ b/src/state.c
@@ -53,6 +53,7 @@ mrb_alloca(mrb_state *mrb, size_t size)
struct alloca_header *p;
p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
+ if (p == NULL) return NULL;
p->next = mrb->mems;
mrb->mems = p;
return (void*)p->buf;
@@ -61,9 +62,12 @@ mrb_alloca(mrb_state *mrb, size_t size)
static void
mrb_alloca_free(mrb_state *mrb)
{
- struct alloca_header *p = mrb->mems;
+ struct alloca_header *p;
struct alloca_header *tmp;
+ if (mrb == NULL) return NULL;
+ p = mrb->mems;
+
while (p) {
tmp = p;
p = p->next;
diff --git a/src/vm.c b/src/vm.c
index dd8edf4bc..65e2f9c65 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -55,12 +55,20 @@ The value below allows about 60000 recursive calls in the simplest case. */
#endif
static inline void
-stack_copy(mrb_value *dst, const mrb_value *src, size_t size)
+stack_clear(mrb_value *from, size_t count)
{
- size_t i;
+ const mrb_value mrb_value_zero = { { 0 } };
+
+ while(count-- > 0) {
+ *from++ = mrb_value_zero;
+ }
+}
- for (i = 0; i < size; i++) {
- dst[i] = src[i];
+static inline void
+stack_copy(mrb_value *dst, const mrb_value *src, size_t size)
+{
+ while (size-- > 0) {
+ *dst++ = *src++;
}
}
@@ -130,15 +138,14 @@ stack_extend(mrb_state *mrb, int room, int keep)
}
if (room > keep) {
- int i;
- for (i=keep; i<room; i++) {
#ifndef MRB_NAN_BOXING
- static const mrb_value mrb_value_zero = { { 0 } };
- mrb->stack[i] = mrb_value_zero;
+ stack_clear(&(mrb->stack[keep]), room - keep);
#else
+ int i;
+ for (i=keep; i<room; i++) {
SET_NIL_VALUE(mrb->stack[i]);
-#endif
}
+#endif
}
}