From e3c8092ccdd3a9991ccd31634e28e9a5a0e29d91 Mon Sep 17 00:00:00 2001 From: Felix Jones Date: Thu, 10 Nov 2016 19:51:56 +0000 Subject: Renamed class_under_defined to class_defined_under --- include/mruby.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index 886b15e50..1b227d41a 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -578,10 +578,10 @@ MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name); * example_outer = mrb_define_module(mrb, "ExampleOuter"); * * example_inner = mrb_define_class_under(mrb, example_outer, "ExampleInner", mrb->object_class); - * cd = mrb_class_under_defined(mrb, example_outer, "ExampleInner"); + * cd = mrb_class_defined_under(mrb, example_outer, "ExampleInner"); * - * // If mrb_class_under_defined returns 1 then puts "True" - * // If mrb_class_under_defined returns 0 then puts "False" + * // If mrb_class_defined_under returns 1 then puts "True" + * // If mrb_class_defined_under returns 0 then puts "False" * if (cd == 1){ * puts("True"); * } @@ -595,7 +595,7 @@ MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name); * @param [const char *] name A string representing the name of the inner class. * @return [mrb_bool] A boolean value. */ -MRB_API mrb_bool mrb_class_under_defined(mrb_state *mrb, struct RClass *outer, const char *name); +MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name); /** * Gets a child class. -- cgit v1.2.3 From c385782cfef484ca9cb07b128d325cfb712de69c Mon Sep 17 00:00:00 2001 From: Tomasz Dąbrowski Date: Mon, 21 Nov 2016 12:03:45 +0100 Subject: mrb_assert definition moved to the beggining of mruby.h So that other files can immediately use it. --- include/mruby.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index 1b227d41a..e6eaf7f27 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -32,6 +32,21 @@ #include #include +#ifdef MRB_DEBUG +#include +#define mrb_assert(p) assert(p) +#define mrb_assert_int_fit(t1,n,t2,max) assert((n)>=0 && ((sizeof(n)<=sizeof(t2))||(n<=(t1)(max)))) +#else +#define mrb_assert(p) ((void)0) +#define mrb_assert_int_fit(t1,n,t2,max) ((void)0) +#endif + +#if __STDC_VERSION__ >= 201112L +#define mrb_static_assert(exp, str) _Static_assert(exp, str) +#else +#define mrb_static_assert(exp, str) mrb_assert(exp) +#endif + #include "mrbconf.h" #include "mruby/common.h" #include @@ -1135,21 +1150,6 @@ MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func); MRB_API void mrb_show_version(mrb_state *mrb); MRB_API void mrb_show_copyright(mrb_state *mrb); -#ifdef MRB_DEBUG -#include -#define mrb_assert(p) assert(p) -#define mrb_assert_int_fit(t1,n,t2,max) assert((n)>=0 && ((sizeof(n)<=sizeof(t2))||(n<=(t1)(max)))) -#else -#define mrb_assert(p) ((void)0) -#define mrb_assert_int_fit(t1,n,t2,max) ((void)0) -#endif - -#if __STDC_VERSION__ >= 201112L -#define mrb_static_assert(exp, str) _Static_assert(exp, str) -#else -#define mrb_static_assert(exp, str) mrb_assert(exp) -#endif - MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...); MRB_END_DECL -- cgit v1.2.3 From 1af9e363f28810e46e263cd13da918cdf779d71d Mon Sep 17 00:00:00 2001 From: Tomasz Dąbrowski Date: Tue, 22 Nov 2016 13:19:05 +0100 Subject: Fixes for compiling mruby as C++ --- include/mruby.h | 16 ++++++++++++++++ include/mruby/boxing_nan.h | 2 +- mrbgems/mruby-inline-struct/test/inline.c | 6 +++--- mrbgems/mruby-objectspace/src/mruby_objectspace.c | 2 +- mrbgems/mruby-sprintf/src/sprintf.c | 12 ++++++------ src/backtrace.c | 4 ++-- src/string.c | 2 +- 7 files changed, 30 insertions(+), 14 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index e6eaf7f27..d40dce6d9 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -28,10 +28,26 @@ #ifndef MRUBY_H #define MRUBY_H +#ifdef __cplusplus +#define __STDC_LIMIT_MACROS +#define __STDC_CONSTANT_MACROS +#define __STDC_FORMAT_MACROS +#endif + #include #include #include +#ifdef __cplusplus +#ifndef SIZE_MAX +#ifdef __SIZE_MAX__ +#define SIZE_MAX __SIZE_MAX__ +#else +#define SIZE_MAX std::numeric_limits::max() +#endif +#endif +#endif + #ifdef MRB_DEBUG #include #define mrb_assert(p) assert(p) diff --git a/include/mruby/boxing_nan.h b/include/mruby/boxing_nan.h index 154150ece..052164ffc 100644 --- a/include/mruby/boxing_nan.h +++ b/include/mruby/boxing_nan.h @@ -53,7 +53,7 @@ typedef struct mrb_value { #define mrb_float_pool(mrb,f) mrb_float_value(mrb,f) #define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1) -#define mrb_type(o) ((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT) +#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT) #define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2)) #define mrb_float(o) (o).f #define mrb_cptr(o) mrb_ptr(o) diff --git a/mrbgems/mruby-inline-struct/test/inline.c b/mrbgems/mruby-inline-struct/test/inline.c index 49ef31d00..772248e9b 100644 --- a/mrbgems/mruby-inline-struct/test/inline.c +++ b/mrbgems/mruby-inline-struct/test/inline.c @@ -6,7 +6,7 @@ static mrb_value istruct_test_initialize(mrb_state *mrb, mrb_value self) { - char *string = mrb_istruct_ptr(self); + char *string = (char*)mrb_istruct_ptr(self); mrb_int size = mrb_istruct_size(); mrb_value object; mrb_get_args(mrb, "o", &object); @@ -31,7 +31,7 @@ istruct_test_initialize(mrb_state *mrb, mrb_value self) static mrb_value istruct_test_to_s(mrb_state *mrb, mrb_value self) { - return mrb_str_new_cstr(mrb, mrb_istruct_ptr(self)); + return mrb_str_new_cstr(mrb, (const char*)mrb_istruct_ptr(self)); } static mrb_value @@ -63,7 +63,7 @@ istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self) static mrb_value istruct_test_mutate(mrb_state *mrb, mrb_value self) { - char *ptr = mrb_istruct_ptr(self); + char *ptr = (char*)mrb_istruct_ptr(self); memcpy(ptr, "mutate", 6); return mrb_nil_value(); } diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index d5cd4f5a1..d0a8effd0 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -49,7 +49,7 @@ static mrb_value os_count_objects(mrb_state *mrb, mrb_value self) { struct os_count_struct obj_count = { 0 }; - enum mrb_vtype i; + mrb_int i; mrb_value hash; if (mrb_get_args(mrb, "|H", &hash) == 0) { diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index ccee23bd2..696d0939f 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -844,13 +844,13 @@ retry: strncpy(nbuf, RSTRING_PTR(val), sizeof(nbuf)); break; case 8: - snprintf(nbuf, sizeof(nbuf), "%"MRB_PRIo, v); + snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIo, v); break; case 10: - snprintf(nbuf, sizeof(nbuf), "%"MRB_PRId, v); + snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); break; case 16: - snprintf(nbuf, sizeof(nbuf), "%"MRB_PRIx, v); + snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIx, v); break; } s = nbuf; @@ -865,13 +865,13 @@ retry: strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); break; case 8: - snprintf(++s, sizeof(nbuf)-1, "%"MRB_PRIo, v); + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v); break; case 10: - snprintf(++s, sizeof(nbuf)-1, "%"MRB_PRId, v); + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v); break; case 16: - snprintf(++s, sizeof(nbuf)-1, "%"MRB_PRIx, v); + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v); break; } if (v < 0) { diff --git a/src/backtrace.c b/src/backtrace.c index 11082b705..285af562f 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -160,7 +160,7 @@ static void output_backtrace_i(mrb_state *mrb, struct backtrace_location_raw *loc_raw, void *data) { struct backtrace_location loc; - struct output_backtrace_args *args = data; + struct output_backtrace_args *args = (struct output_backtrace_args *)data; loc.i = loc_raw->i; loc.lineno = loc_raw->lineno; @@ -338,7 +338,7 @@ save_backtrace_i(mrb_state *mrb, else { new_n_allocated = mrb->backtrace.n_allocated * 2; } - mrb->backtrace.entries = + mrb->backtrace.entries = (mrb_backtrace_entry *) mrb_realloc(mrb, mrb->backtrace.entries, sizeof(mrb_backtrace_entry) * new_n_allocated); diff --git a/src/string.c b/src/string.c index f8ab9478f..5e490bf03 100644 --- a/src/string.c +++ b/src/string.c @@ -361,7 +361,7 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) return 0; } else if (m == 1) { - const unsigned char *ys = memchr(y, *x, n); + const unsigned char *ys = (const unsigned char *)memchr(y, *x, n); if (ys) return ys - y; -- cgit v1.2.3 From 72ed7eebc30eaccf4175eaa7f62235bcb7a8901d Mon Sep 17 00:00:00 2001 From: Tomasz Dąbrowski Date: Thu, 24 Nov 2016 12:50:49 +0100 Subject: Fixed Range.size to use proper floating point tolerance --- include/mruby.h | 7 +++++++ mrbgems/mruby-range-ext/src/range.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index d40dce6d9..bc6800e29 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -64,6 +64,13 @@ #endif #include "mrbconf.h" + +#ifdef MRB_USE_FLOAT +#define MRB_FLOAT_EPSILON FLT_EPSILON +#else +#define MRB_FLOAT_EPSILON DBL_EPSILON +#endif + #include "mruby/common.h" #include #include diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index 32222a594..ccb5a9e45 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -140,7 +140,7 @@ mrb_range_size(mrb_state *mrb, mrb_value range) } if (num_p) { mrb_float n = end_f - beg_f; - mrb_float err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * DBL_EPSILON; + mrb_float err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * MRB_FLOAT_EPSILON; if (err>0.5) err=0.5; if (excl) { -- cgit v1.2.3 From f9f19f34dd8b267895fb61223b194a6ae6bdc89e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 27 Nov 2016 20:53:25 +0900 Subject: replace _cstr by _lit for litral C strings; ref #3300 --- include/mruby.h | 10 +++++----- include/mruby/string.h | 12 ++++++------ include/mruby/variable.h | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index bc6800e29..1e27b93fb 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -430,7 +430,7 @@ MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_ * * mrb_value * mrb_example_method(mrb_state *mrb){ - * return mrb_str_new_cstr(mrb, "example"); + * return mrb_str_new_lit(mrb, "example"); * } * * void @@ -473,7 +473,7 @@ MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*); * * mrb_value * mrb_example_method(mrb_state *mrb){ - * return mrb_str_new_cstr(mrb, "example"); + * return mrb_str_new_lit(mrb, "example"); * } * * void @@ -696,7 +696,7 @@ MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char * * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); * mrb_define_method(mrb, example_class, "example_method", exampleMethod, MRB_ARGS_NONE()); - * mid = mrb_intern_str(mrb, mrb_str_new_cstr(mrb, "example_method" )); + * mid = mrb_intern_str(mrb, mrb_str_new_lit(mrb, "example_method" )); * obj_resp = mrb_obj_respond_to(mrb, example_class, mid); // => 1(true in Ruby world) * * // If mrb_obj_respond_to returns 1 then puts "True" @@ -884,7 +884,7 @@ MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...); * mrb_state *mrb = mrb_open(); * * if (!mrb) { } - * mrb_sym m_sym = mrb_intern_cstr(mrb, "method_name"); // Symbol for method. + * mrb_sym m_sym = mrb_intern_lit(mrb, "method_name"); // Symbol for method. * * FILE *fp = fopen("test.rb","r"); * mrb_value obj = mrb_load_file(mrb,fp); @@ -912,7 +912,7 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int * :pizza # => :pizza * * // C style: - * mrb_sym m_sym = mrb_intern_cstr(mrb, "pizza"); // => :pizza + * mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); // => :pizza * @param [mrb_state*] mrb_state* The current mruby state. * @param [const char*] const char* The name of the method. * @return [mrb_sym] mrb_sym A symbol. diff --git a/include/mruby/string.h b/include/mruby/string.h index e45846e87..b30c1ed98 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -110,8 +110,8 @@ MRB_API void mrb_str_modify(mrb_state*, struct RString*); * } * * // Creates new Ruby strings. - * str1 = mrb_str_new_cstr(mrb, "abc"); - * str2 = mrb_str_new_cstr(mrb, "def"); + * str1 = mrb_str_new_lit(mrb, "abc"); + * str2 = mrb_str_new_lit(mrb, "def"); * * // Concatnates str2 to str1. * mrb_str_concat(mrb, str1, str2); @@ -158,8 +158,8 @@ MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value); * } * * // Creates two Ruby strings from the passed in C strings. - * a = mrb_str_new_cstr(mrb, "abc"); - * b = mrb_str_new_cstr(mrb, "def"); + * a = mrb_str_new_lit(mrb, "abc"); + * b = mrb_str_new_lit(mrb, "def"); * * // Prints both C strings. * mrb_p(mrb, a); @@ -227,7 +227,7 @@ MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj); * // handle error * } * // Creates a new string. - * str = mrb_str_new_cstr(mrb, "Hello, world!"); + * str = mrb_str_new_lit(mrb, "Hello, world!"); * // Returns 5 characters of * mrb_str_resize(mrb, str, 5); * mrb_p(mrb, str); @@ -267,7 +267,7 @@ MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len); * // handle error * } * // Creates new string. - * str1 = mrb_str_new_cstr(mrb, "Hello, world!"); + * str1 = mrb_str_new_lit(mrb, "Hello, world!"); * // Returns a sub-string within the range of 0..2 * str2 = mrb_str_substr(mrb, str1, 0, 2); * diff --git a/include/mruby/variable.h b/include/mruby/variable.h index 8b1cc2eef..2f2bbbf98 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -66,7 +66,7 @@ MRB_API mrb_bool mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id) * * !!!c * // C style - * mrb_sym sym = mrb_intern_cstr(mrb, "$value"); + * mrb_sym sym = mrb_intern_lit(mrb, "$value"); * mrb_value var = mrb_gv_get(mrb, sym); * * @param mrb The mruby state reference @@ -86,8 +86,8 @@ MRB_API mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym); * * !!!c * // C style - * mrb_sym sym = mrb_intern_cstr(mrb, "$value"); - * mrb_gv_set(mrb, sym, mrb_str_new_cstr("foo")); + * mrb_sym sym = mrb_intern_lit(mrb, "$value"); + * mrb_gv_set(mrb, sym, mrb_str_new_lit("foo")); * * @param mrb The mruby state reference * @param sym The name of the global variable @@ -106,7 +106,7 @@ MRB_API void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val); * * !!!c * // C style - * mrb_sym sym = mrb_intern_cstr(mrb, "$value"); + * mrb_sym sym = mrb_intern_lit(mrb, "$value"); * mrb_gv_remove(mrb, sym); * * @param mrb The mruby state reference -- cgit v1.2.3 From 9fc62d28d0e5738368571d70f1be191876e91d8b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 28 Nov 2016 09:52:57 +0900 Subject: pre-allocate arena overflow error --- include/mruby.h | 3 +++ src/error.c | 5 ++++- src/gc.c | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index 1e27b93fb..6e222057f 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -221,6 +221,9 @@ typedef struct mrb_state { struct RClass *eException_class; struct RClass *eStandardError_class; struct RObject *nomem_err; /* pre-allocated NoMemoryError */ +#ifdef MRB_GC_FIXED_ARENA + struct RObject *arena_err; /* pre-allocated arena overfow error */ +#endif void *ud; /* auxiliary data */ diff --git a/src/error.c b/src/error.c index 9ff570bf6..b24aed798 100644 --- a/src/error.c +++ b/src/error.c @@ -465,7 +465,7 @@ exception_call: } if (argc > 0) { if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) - mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); + mrb_raise(mrb, mrb->eException_class, "exception object expected"); if (argc > 2) set_backtrace(mrb, mesg, argv[2]); } @@ -532,6 +532,9 @@ mrb_init_exception(mrb_state *mrb) mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "Out of memory")); +#ifdef MRB_GC_FIXED_ARENA + mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "arena overflow error")); +#endif script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ mrb_define_class(mrb, "SystemStackError", exception); diff --git a/src/gc.c b/src/gc.c index b29df1f02..ecc09374e 100644 --- a/src/gc.c +++ b/src/gc.c @@ -403,7 +403,7 @@ gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) if (gc->arena_idx >= MRB_GC_ARENA_SIZE) { /* arena overflow error */ gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */ - mrb_raise(mrb, E_RUNTIME_ERROR, "arena overflow error"); + mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err)); } #else if (gc->arena_idx >= gc->arena_capa) { @@ -816,6 +816,9 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc) mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); /* mark pre-allocated exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err); +#ifdef MRB_GC_FIXED_ARENA + mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); +#endif mark_context(mrb, mrb->root_c); if (mrb->root_c->fib) { -- cgit v1.2.3 From 2c77dfab0499863a71d4bebef665947c603fe4fa Mon Sep 17 00:00:00 2001 From: Daniel Bovensiepen Date: Fri, 6 Jan 2017 14:27:57 +0800 Subject: Update Copyright to 2017 Signed-off-by: Daniel Bovensiepen --- MITL | 2 +- include/mruby.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/mruby.h') diff --git a/MITL b/MITL index 38fdbe231..d02b8fe1c 100644 --- a/MITL +++ b/MITL @@ -1,4 +1,4 @@ -Copyright (c) 2016 mruby developers +Copyright (c) 2017 mruby developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/include/mruby.h b/include/mruby.h index 6e222057f..76a028ad4 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1,7 +1,7 @@ /* ** mruby - An embeddable Ruby implementation ** -** Copyright (c) mruby developers 2010-2016 +** Copyright (c) mruby developers 2010-2017 ** ** Permission is hereby granted, free of charge, to any person obtaining ** a copy of this software and associated documentation files (the -- cgit v1.2.3 From 44edc51612536a9e23dabf7c87afc3996efde027 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 11 Jan 2017 09:53:31 +0900 Subject: Raises Exception if raising exception class is redefined close #3384 This issue was reported by https://hackerone.com/brakhane --- include/mruby.h | 44 ++++++++++++++++++++++++++------------------ src/class.c | 14 ++++++++++++++ 2 files changed, 40 insertions(+), 18 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index 76a028ad4..99d06146f 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -607,6 +607,14 @@ MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name); */ MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name); +/** + * Gets a exception class. + * @param [mrb_state*] mrb The current mruby state. + * @param [const char *] name The name of the class. + * @return [struct RClass *] A reference to the class. +*/ +MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name); + /** * Returns an mrb_bool. True if inner class was defined, and false if the inner class was not defined. * @@ -1091,23 +1099,23 @@ MRB_API void mrb_print_error(mrb_state *mrb); + those E_* macros requires mrb_state* variable named mrb. + exception objects obtained from those macros are local to mrb */ -#define E_RUNTIME_ERROR (mrb_class_get(mrb, "RuntimeError")) -#define E_TYPE_ERROR (mrb_class_get(mrb, "TypeError")) -#define E_ARGUMENT_ERROR (mrb_class_get(mrb, "ArgumentError")) -#define E_INDEX_ERROR (mrb_class_get(mrb, "IndexError")) -#define E_RANGE_ERROR (mrb_class_get(mrb, "RangeError")) -#define E_NAME_ERROR (mrb_class_get(mrb, "NameError")) -#define E_NOMETHOD_ERROR (mrb_class_get(mrb, "NoMethodError")) -#define E_SCRIPT_ERROR (mrb_class_get(mrb, "ScriptError")) -#define E_SYNTAX_ERROR (mrb_class_get(mrb, "SyntaxError")) -#define E_LOCALJUMP_ERROR (mrb_class_get(mrb, "LocalJumpError")) -#define E_REGEXP_ERROR (mrb_class_get(mrb, "RegexpError")) -#define E_SYSSTACK_ERROR (mrb_class_get(mrb, "SystemStackError")) - -#define E_NOTIMP_ERROR (mrb_class_get(mrb, "NotImplementedError")) -#define E_FLOATDOMAIN_ERROR (mrb_class_get(mrb, "FloatDomainError")) - -#define E_KEY_ERROR (mrb_class_get(mrb, "KeyError")) +#define E_RUNTIME_ERROR (mrb_exc_get(mrb, "RuntimeError")) +#define E_TYPE_ERROR (mrb_exc_get(mrb, "TypeError")) +#define E_ARGUMENT_ERROR (mrb_exc_get(mrb, "ArgumentError")) +#define E_INDEX_ERROR (mrb_exc_get(mrb, "IndexError")) +#define E_RANGE_ERROR (mrb_exc_get(mrb, "RangeError")) +#define E_NAME_ERROR (mrb_exc_get(mrb, "NameError")) +#define E_NOMETHOD_ERROR (mrb_exc_get(mrb, "NoMethodError")) +#define E_SCRIPT_ERROR (mrb_exc_get(mrb, "ScriptError")) +#define E_SYNTAX_ERROR (mrb_exc_get(mrb, "SyntaxError")) +#define E_LOCALJUMP_ERROR (mrb_exc_get(mrb, "LocalJumpError")) +#define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError")) +#define E_SYSSTACK_ERROR (mrb_exc_get(mrb, "SystemStackError")) + +#define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError")) +#define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError")) + +#define E_KEY_ERROR (mrb_exc_get(mrb, "KeyError")) MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg); MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv); @@ -1160,7 +1168,7 @@ MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int argc, const mrb_value * * @mrbgem mruby-fiber */ -#define E_FIBER_ERROR (mrb_class_get(mrb, "FiberError")) +#define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError")) /* memory pool implementation */ typedef struct mrb_pool mrb_pool; diff --git a/src/class.c b/src/class.c index fed259b5b..cb7bdfddd 100644 --- a/src/class.c +++ b/src/class.c @@ -317,6 +317,20 @@ mrb_class_get(mrb_state *mrb, const char *name) return mrb_class_get_under(mrb, mrb->object_class, name); } +MRB_API struct RClass * +mrb_exc_get(mrb_state *mrb, const char *name) +{ + struct RClass *exc = mrb_class_get_under(mrb, mrb->object_class, name); + struct RClass *e = exc; + + while (e) { + if (e == mrb->eException_class) + return exc; + e = e->super; + } + return mrb->eException_class; +} + MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name) { -- cgit v1.2.3 From 30aa5218543cd44df7c1d90a5c10cf6f622f5a8a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 14 Feb 2017 00:22:12 +0900 Subject: Do not use mrb_funcall() if Hash#default is not overridden; ref #3421 This change reduces the recursion level, but does not solve the stack overflow issue entirely. --- include/mruby.h | 1 + src/hash.c | 21 ++++++++++++++++++++- src/kernel.c | 14 ++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index 99d06146f..6950cf904 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1147,6 +1147,7 @@ MRB_API mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id); MRB_API mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid); MRB_API mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c); +MRB_API mrb_bool mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func); /* diff --git a/src/hash.c b/src/hash.c index 98feaceac..b7bd648c0 100644 --- a/src/hash.c +++ b/src/hash.c @@ -159,6 +159,9 @@ mrb_hash_new(mrb_state *mrb) return mrb_hash_new_capa(mrb, 0); } +static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash); +static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key); + MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) { @@ -171,7 +174,9 @@ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) return kh_value(h, k).v; } - /* not found */ + if (mrb_func_basic_p(mrb, hash, mrb_intern_lit(mrb, "default"), mrb_hash_default)) { + return hash_default(mrb, hash, key); + } /* xxx mrb_funcall_tailcall(mrb, hash, "default", 1, key); */ return mrb_funcall(mrb, hash, "default", 1, key); } @@ -366,6 +371,20 @@ mrb_hash_aget(mrb_state *mrb, mrb_value self) return mrb_hash_get(mrb, self, key); } +static mrb_value +hash_default(mrb_state *mrb, mrb_value hash, mrb_value key) +{ + if (MRB_RHASH_DEFAULT_P(hash)) { + if (MRB_RHASH_PROCDEFAULT_P(hash)) { + return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); + } + else { + return RHASH_IFNONE(hash); + } + } + return mrb_nil_value(); +} + /* 15.2.13.4.5 */ /* * call-seq: diff --git a/src/kernel.c b/src/kernel.c index 8b00d701b..02bb3c99b 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -28,15 +28,21 @@ typedef enum { NOEX_RESPONDS = 0x80 } mrb_method_flag_t; -static mrb_bool -mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj) +MRB_API mrb_bool +mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func) { - struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern_lit(mrb, "to_s")); - if (MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s)) + struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid); + if (MRB_PROC_CFUNC_P(me) && (me->body.func == func)) return TRUE; return FALSE; } +static mrb_bool +mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj) +{ + return mrb_func_basic_p(mrb, obj, mrb_intern_lit(mrb, "to_s"), mrb_any_to_s); +} + /* 15.3.1.3.17 */ /* * call-seq: -- cgit v1.2.3 From 8efa7b00df2842eaff31cdabc95651a856e40549 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 15 Feb 2017 11:59:47 +0900 Subject: Preallocate SystemStackError; ref #3421 --- include/mruby.h | 2 +- src/backtrace.c | 2 +- src/error.c | 5 +++-- src/gc.c | 1 + src/vm.c | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) (limited to 'include/mruby.h') diff --git a/include/mruby.h b/include/mruby.h index 6950cf904..8adce289b 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -221,6 +221,7 @@ typedef struct mrb_state { struct RClass *eException_class; struct RClass *eStandardError_class; struct RObject *nomem_err; /* pre-allocated NoMemoryError */ + struct RObject *stack_err; /* pre-allocated SysStackError */ #ifdef MRB_GC_FIXED_ARENA struct RObject *arena_err; /* pre-allocated arena overfow error */ #endif @@ -1110,7 +1111,6 @@ MRB_API void mrb_print_error(mrb_state *mrb); #define E_SYNTAX_ERROR (mrb_exc_get(mrb, "SyntaxError")) #define E_LOCALJUMP_ERROR (mrb_exc_get(mrb, "LocalJumpError")) #define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError")) -#define E_SYSSTACK_ERROR (mrb_exc_get(mrb, "SystemStackError")) #define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError")) #define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError")) diff --git a/src/backtrace.c b/src/backtrace.c index 051d5d4e0..529b0b1c9 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -263,7 +263,7 @@ mrb_print_backtrace(mrb_state *mrb) { mrb_value backtrace; - if (!mrb->exc || mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), E_SYSSTACK_ERROR)) { + if (!mrb->exc) { return; } diff --git a/src/error.c b/src/error.c index a71ee548f..7916ca65b 100644 --- a/src/error.c +++ b/src/error.c @@ -532,7 +532,7 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, void mrb_init_exception(mrb_state *mrb) { - struct RClass *exception, *runtime_error, *script_error; + struct RClass *exception, *runtime_error, *script_error, *stack_error; mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); @@ -553,5 +553,6 @@ mrb_init_exception(mrb_state *mrb) #endif script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ - mrb_define_class(mrb, "SystemStackError", exception); + stack_error = mrb_define_class(mrb, "SystemStackError", exception); + mrb->stack_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, stack_error, "stack level too deep")); } diff --git a/src/gc.c b/src/gc.c index 1608dbcb2..63eab8e00 100644 --- a/src/gc.c +++ b/src/gc.c @@ -865,6 +865,7 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc) } /* mark pre-allocated exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err); + mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err); #ifdef MRB_GC_FIXED_ARENA mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); #endif diff --git a/src/vm.c b/src/vm.c index 8bb446fa9..91612a0da 100644 --- a/src/vm.c +++ b/src/vm.c @@ -162,7 +162,7 @@ stack_extend_alloc(mrb_state *mrb, int room, int keep) to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */ if (size > MRB_STACK_MAX) { init_new_stack_space(mrb, room, keep); - mrb_raise(mrb, E_SYSSTACK_ERROR, "stack level too deep. (limit=" MRB_STRINGIZE(MRB_STACK_MAX) ")"); + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } } -- cgit v1.2.3