diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/mrbconf.h | 85 | ||||
| -rw-r--r-- | include/mruby.h | 161 | ||||
| -rw-r--r-- | include/mruby/array.h | 25 | ||||
| -rw-r--r-- | include/mruby/boxing_nan.h | 111 | ||||
| -rw-r--r-- | include/mruby/boxing_no.h | 14 | ||||
| -rw-r--r-- | include/mruby/boxing_word.h | 123 | ||||
| -rw-r--r-- | include/mruby/class.h | 19 | ||||
| -rw-r--r-- | include/mruby/compile.h | 4 | ||||
| -rw-r--r-- | include/mruby/debug.h | 2 | ||||
| -rw-r--r-- | include/mruby/dump.h | 38 | ||||
| -rw-r--r-- | include/mruby/endian.h | 44 | ||||
| -rw-r--r-- | include/mruby/error.h | 44 | ||||
| -rw-r--r-- | include/mruby/hash.h | 2 | ||||
| -rw-r--r-- | include/mruby/irep.h | 65 | ||||
| -rw-r--r-- | include/mruby/numeric.h | 31 | ||||
| -rw-r--r-- | include/mruby/opcode.h | 27 | ||||
| -rw-r--r-- | include/mruby/ops.h | 12 | ||||
| -rw-r--r-- | include/mruby/presym.h | 25 | ||||
| -rw-r--r-- | include/mruby/proc.h | 20 | ||||
| -rw-r--r-- | include/mruby/string.h | 15 | ||||
| -rw-r--r-- | include/mruby/throw.h | 12 | ||||
| -rw-r--r-- | include/mruby/value.h | 45 |
22 files changed, 572 insertions, 352 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h index 2b1adb24e..89b3e9022 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -25,33 +25,69 @@ #endif /* configuration options: */ -/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */ -//#define MRB_USE_FLOAT +/* add -DMRB_USE_FLOAT32 to use float instead of double for floating point numbers */ +//#define MRB_USE_FLOAT32 /* exclude floating point numbers */ -//#define MRB_WITHOUT_FLOAT +//#define MRB_NO_FLOAT -/* add -DMRB_METHOD_CACHE to use method cache to improve performance */ -//#define MRB_METHOD_CACHE +/* obsolete configuration */ +#if defined(MRB_USE_FLOAT) +# define MRB_USE_FLOAT32 +#endif + +/* obsolete configuration */ +#if defined(MRB_WITHOUT_FLOAT) +# define MRB_NO_FLOAT +#endif + +#if defined(MRB_USE_FLOAT32) && defined(MRB_NO_FLOAT) +#error Cannot define MRB_USE_FLOAT32 and MRB_NO_FLOAT at the same time +#endif + +/* add -DMRB_NO_METHOD_CACHE to disable method cache to save memory */ +//#define MRB_NO_METHOD_CACHE /* size of the method cache (need to be the power of 2) */ -//#define MRB_METHOD_CACHE_SIZE (1<<7) +//#define MRB_METHOD_CACHE_SIZE (1<<8) -/* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */ -/* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */ -#ifndef MRB_METHOD_T_STRUCT +/* add -DMRB_USE_METHOD_T_STRUCT on machines that use higher bits of function pointers */ +/* no MRB_USE_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */ +#ifndef MRB_USE_METHOD_T_STRUCT // can't use highest 2 bits of function pointers at least on 32bit // Windows and 32bit Linux. # ifdef MRB_32BIT -# define MRB_METHOD_T_STRUCT +# define MRB_USE_METHOD_T_STRUCT +# endif +#endif + +/* define on big endian machines; used by MRB_NAN_BOXING, etc. */ +#ifndef MRB_ENDIAN_BIG +# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define MRB_ENDIAN_BIG # endif #endif +/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT32 and MRB_NO_FLOAT */ +//#define MRB_NAN_BOXING + +/* represent mrb_value as a word (natural unit of data for the processor) */ +//#define MRB_WORD_BOXING + +/* represent mrb_value as a struct; occupies 2 words */ +//#define MRB_NO_BOXING + +/* if no specific boxing type is chosen */ +#if !defined(MRB_NAN_BOXING) && !defined(MRB_WORD_BOXING) && !defined(MRB_NO_BOXING) +# define MRB_WORD_BOXING +#endif + /* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64; Default for 32-bit CPU mode. */ //#define MRB_INT32 /* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT32; - Default for 64-bit CPU mode. */ + Default for 64-bit CPU mode (unless using MRB_NAN_BOXING). */ //#define MRB_INT64 /* if no specific integer type is chosen */ @@ -65,19 +101,8 @@ # endif #endif -/* define on big endian machines; used by MRB_NAN_BOXING, etc. */ -#ifndef MRB_ENDIAN_BIG -# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \ - (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -# define MRB_ENDIAN_BIG -# endif -#endif - -/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT and MRB_WITHOUT_FLOAT */ -//#define MRB_NAN_BOXING - -/* represent mrb_value as a word (natural unit of data for the processor) */ -//#define MRB_WORD_BOXING +/* call malloc_trim(0) from mrb_full_gc() */ +//#define MRB_USE_MALLOC_TRIM /* string class to handle UTF-8 encoding */ //#define MRB_UTF8_STRING @@ -160,6 +185,10 @@ /* A profile for micro controllers */ #if defined(MRB_CONSTRAINED_BASELINE_PROFILE) +# ifndef MRB_NO_METHOD_CACHE +# define MRB_NO_METHOD_CACHE +# endif + # ifndef KHASH_DEFAULT_SIZE # define KHASH_DEFAULT_SIZE 16 # endif @@ -177,10 +206,6 @@ /* A profile for desktop computers or workstations; rich memory! */ #elif defined(MRB_MAIN_PROFILE) -# ifndef MRB_METHOD_CACHE -# define MRB_METHOD_CACHE -# endif - # ifndef MRB_METHOD_CACHE_SIZE # define MRB_METHOD_CACHE_SIZE (1<<10) # endif @@ -195,10 +220,6 @@ /* A profile for server; mruby vm is long life */ #elif defined(MRB_HIGH_PROFILE) -# ifndef MRB_METHOD_CACHE -# define MRB_METHOD_CACHE -# endif - # ifndef MRB_METHOD_CACHE_SIZE # define MRB_METHOD_CACHE_SIZE (1<<12) # endif diff --git a/include/mruby.h b/include/mruby.h index 6d884b146..52bcd58bf 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -89,9 +89,10 @@ #include <mruby/common.h> #include <mruby/value.h> #include <mruby/gc.h> +#include <mruby/presym.h> #include <mruby/version.h> -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT #include <float.h> #ifndef FLT_EPSILON #define FLT_EPSILON (1.19209290e-07f) @@ -103,7 +104,7 @@ #define LDBL_EPSILON (1.08420217248550443401e-19L) #endif -#ifdef MRB_USE_FLOAT +#ifdef MRB_USE_FLOAT32 #define MRB_FLOAT_EPSILON FLT_EPSILON #else #define MRB_FLOAT_EPSILON DBL_EPSILON @@ -146,15 +147,13 @@ typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud); typedef struct { mrb_sym mid; - struct RProc *proc; + const struct RProc *proc; mrb_value *stackent; - uint16_t ridx; - uint16_t epos; struct REnv *env; const mrb_code *pc; /* return address */ const mrb_code *err; /* error position */ - int argc; - int acc; + mrb_int argc; + mrb_int acc; struct RClass *target_class; } mrb_callinfo; @@ -176,22 +175,17 @@ struct mrb_context { mrb_callinfo *ci; mrb_callinfo *cibase, *ciend; - uint16_t *rescue; /* exception handler stack */ - uint16_t rsize; - struct RProc **ensure; /* ensure handler stack */ - uint16_t esize, eidx; - enum mrb_fiber_state status : 4; mrb_bool vmexec : 1; struct RFiber *fib; }; #ifdef MRB_METHOD_CACHE_SIZE -# define MRB_METHOD_CACHE +# undef MRB_NO_METHOD_CACHE #else -/* default method cache size: 128 */ +/* default method cache size: 256 */ /* cache size needs to be power of 2 */ -# define MRB_METHOD_CACHE_SIZE (1<<7) +# define MRB_METHOD_CACHE_SIZE (1<<8) #endif /** @@ -205,7 +199,7 @@ struct mrb_context { */ typedef mrb_value (*mrb_func_t)(struct mrb_state *mrb, mrb_value self); -#ifndef MRB_METHOD_T_STRUCT +#ifndef MRB_USE_METHOD_T_STRUCT typedef uintptr_t mrb_method_t; #else typedef struct { @@ -217,7 +211,7 @@ typedef struct { } mrb_method_t; #endif -#ifdef MRB_METHOD_CACHE +#ifndef MRB_NO_METHOD_CACHE struct mrb_cache_entry { struct RClass *c, *c0; mrb_sym mid; @@ -251,10 +245,10 @@ typedef struct mrb_state { struct RClass *hash_class; struct RClass *range_class; -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT struct RClass *float_class; #endif - struct RClass *fixnum_class; + struct RClass *integer_class; struct RClass *true_class; struct RClass *false_class; struct RClass *nil_class; @@ -263,7 +257,7 @@ typedef struct mrb_state { mrb_gc gc; -#ifdef MRB_METHOD_CACHE +#ifndef MRB_NO_METHOD_CACHE struct mrb_cache_entry cache[MRB_METHOD_CACHE_SIZE]; #endif @@ -276,8 +270,8 @@ typedef struct mrb_state { #endif #ifdef MRB_ENABLE_DEBUG_HOOK - void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs); - void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs); + void (*code_fetch_hook)(struct mrb_state* mrb, const struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs); + void (*debug_op_hook)(struct mrb_state* mrb, const struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs); #endif #ifdef MRB_BYTECODE_DECODE_OPTION @@ -300,7 +294,6 @@ typedef struct mrb_state { mrb_atexit_func *atexit_stack; #endif uint16_t atexit_stack_len; - uint16_t ecall_nest; /* prevent infinite recursive ecall() */ } mrb_state; /** @@ -325,6 +318,7 @@ typedef struct mrb_state { * @see mrb_define_class_under */ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super); +MRB_API struct RClass *mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super); /** * Defines a new module. @@ -334,6 +328,7 @@ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct * @return [struct RClass *] Reference to the newly defined module. */ MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name); +MRB_API struct RClass *mrb_define_module_id(mrb_state *mrb, mrb_sym name); MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val); MRB_API struct RClass *mrb_singleton_class_ptr(mrb_state *mrb, mrb_value val); @@ -389,6 +384,7 @@ MRB_API void mrb_prepend_module(mrb_state *mrb, struct RClass *cla, struct RClas * @param aspec The method parameters declaration. */ MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec); +MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec); /** * Defines a class method. @@ -416,6 +412,7 @@ MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *n * @param aspec The method parameters declaration. */ MRB_API void mrb_define_class_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec); +MRB_API void mrb_define_class_method_id(mrb_state *mrb, struct RClass *cla, mrb_sym name, mrb_func_t fun, mrb_aspec aspec); /** * Defines a singleton method @@ -423,6 +420,7 @@ MRB_API void mrb_define_class_method(mrb_state *mrb, struct RClass *cla, const c * @see mrb_define_class_method */ MRB_API void mrb_define_singleton_method(mrb_state *mrb, struct RObject *cla, const char *name, mrb_func_t fun, mrb_aspec aspec); +MRB_API void mrb_define_singleton_method_id(mrb_state *mrb, struct RObject *cla, mrb_sym name, mrb_func_t fun, mrb_aspec aspec); /** * Defines a module function. @@ -450,6 +448,7 @@ MRB_API void mrb_define_singleton_method(mrb_state *mrb, struct RObject *cla, co * @param aspec The method parameters declaration. */ MRB_API void mrb_define_module_function(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec); +MRB_API void mrb_define_module_function_id(mrb_state *mrb, struct RClass *cla, mrb_sym name, mrb_func_t fun, mrb_aspec aspec); /** * Defines a constant. @@ -478,6 +477,7 @@ MRB_API void mrb_define_module_function(mrb_state *mrb, struct RClass *cla, cons * @param val The value for the constant. */ MRB_API void mrb_define_const(mrb_state* mrb, struct RClass* cla, const char *name, mrb_value val); +MRB_API void mrb_define_const_id(mrb_state* mrb, struct RClass* cla, mrb_sym name, mrb_value val); /** * Undefines a method. @@ -568,6 +568,7 @@ MRB_API void mrb_undef_method_id(mrb_state*, struct RClass*, mrb_sym); * @param name The name of the class method to be undefined. */ MRB_API void mrb_undef_class_method(mrb_state *mrb, struct RClass *cls, const char *name); +MRB_API void mrb_undef_class_method_id(mrb_state *mrb, struct RClass *cls, mrb_sym name); /** * Initialize a new object instance of c class. @@ -669,6 +670,7 @@ MRB_API struct RClass * mrb_module_new(mrb_state *mrb); * @return [mrb_bool] A boolean value. */ MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name); +MRB_API mrb_bool mrb_class_defined_id(mrb_state *mrb, mrb_sym name); /** * Gets a class. @@ -676,7 +678,8 @@ MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name); * @param name The name of the class. * @return [struct RClass *] A reference to the class. */ -MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name); +MRB_API struct RClass* mrb_class_get(mrb_state *mrb, const char *name); +MRB_API struct RClass* mrb_class_get_id(mrb_state *mrb, mrb_sym name); /** * Gets a exception class. @@ -684,7 +687,8 @@ MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name); * @param 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); +MRB_API struct RClass* mrb_exc_get_id(mrb_state *mrb, mrb_sym name); +#define mrb_exc_get(mrb, name) mrb_exc_get_id(mrb, mrb_intern_cstr(mrb, name)) /** * Returns an mrb_bool. True if inner class was defined, and false if the inner class was not defined. @@ -716,6 +720,7 @@ MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name); * @return [mrb_bool] A boolean value. */ MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name); +MRB_API mrb_bool mrb_class_defined_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name); /** * Gets a child class. @@ -725,6 +730,7 @@ MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, c * @return [struct RClass *] A reference to the class. */ MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name); +MRB_API struct RClass * mrb_class_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name); /** * Gets a module. @@ -733,6 +739,7 @@ MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer * @return [struct RClass *] A reference to the module. */ MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name); +MRB_API struct RClass * mrb_module_get_id(mrb_state *mrb, mrb_sym name); /** * Gets a module defined under another module. @@ -742,6 +749,8 @@ MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name); * @return [struct RClass *] A reference to the module. */ MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name); +MRB_API struct RClass * mrb_module_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name); + /* a function to raise NotImplementedError with current method name */ MRB_API void mrb_notimplement(mrb_state*); /* a function to be replacement of unimplemented method */ @@ -810,9 +819,11 @@ MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mi * @return [struct RClass *] Reference to the newly defined class * @see mrb_define_class */ -MRB_API struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super); +MRB_API struct RClass* mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super); +MRB_API struct RClass* mrb_define_class_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name, struct RClass *super); -MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name); +MRB_API struct RClass* mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name); +MRB_API struct RClass* mrb_define_module_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name); /** * Function requires n arguments. @@ -879,8 +890,8 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o * | `s` | {String} | const char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` | * | `z` | {String} | const char * | `NULL` terminated string; `z!` gives `NULL` for `nil` | * | `a` | {Array} | {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` | - * | `f` | {Fixnum}/{Float} | {mrb_float} | | - * | `i` | {Fixnum}/{Float} | {mrb_int} | | + * | `f` | {Integer}/{Float} | {mrb_float} | | + * | `i` | {Integer}/{Float} | {mrb_int} | | * | `b` | boolean | {mrb_bool} | | * | `n` | {String}/{Symbol} | {mrb_sym} | | * | `d` | data | void *, {mrb_data_type} const | 2nd argument will be used to check data type so it won't be modified; when `!` follows, the value may be `nil` | @@ -918,7 +929,7 @@ typedef const char *mrb_args_format; * const char *kw_names[kw_num] = { "a", "b" }; * uint32_t kw_required = 0; * mrb_value kw_values[kw_num]; - * const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, NULL }; + * const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL }; * * mrb_get_args(mrb, ":", &kwargs); * if (mrb_undef_p(kw_values[0])) { kw_values[0] = mrb_fixnum_value(1); } @@ -929,10 +940,10 @@ typedef const char *mrb_args_format; * * mrb_value str, kw_rest; * uint32_t kw_num = 3; - * const char *kw_names[kw_num] = { "x", "y", "z" }; + * const mrb_sym kw_names[kw_num] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) }; * uint32_t kw_required = 1; * mrb_value kw_values[kw_num]; - * const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, &kw_rest }; + * const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest }; * * mrb_get_args(mrb, "S:", &str, &kwargs); * // or: mrb_get_args(mrb, ":S", &kwargs, &str); @@ -943,11 +954,11 @@ typedef struct mrb_kwargs mrb_kwargs; struct mrb_kwargs { - uint32_t num; - mrb_value *values; - const char *const *table; - uint32_t required; - mrb_value *rest; + uint32_t num; /* number of keyword arguments */ + uint32_t required; /* number of required keyword arguments */ + const mrb_sym *table; /* C array of symbols for keyword names */ + mrb_value *values; /* keyword argument values */ + mrb_value *rest; /* keyword rest (dict) */ }; /** @@ -1017,6 +1028,7 @@ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb); * FILE *fp = fopen("test.rb","r"); * mrb_value obj = mrb_load_file(mrb,fp); * mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i)); + * mrb_funcall_id(mrb, obj, MRB_SYM(method_name), 1, mrb_fixnum_value(i)); * fclose(fp); * mrb_close(mrb); * } @@ -1029,6 +1041,7 @@ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb); * @return [mrb_value] mruby function value. */ MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, mrb_int argc, ...); +MRB_API mrb_value mrb_funcall_id(mrb_state *mrb, mrb_value val, mrb_sym mid, mrb_int argc, ...); /** * Call existing ruby functions. This is basically the type safe version of mrb_funcall. * @@ -1038,15 +1051,14 @@ MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, m * int * main() * { - * mrb_int i = 99; * mrb_state *mrb = mrb_open(); + * mrb_value obj = mrb_fixnum_value(1); * * if (!mrb) { } - * 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); - * mrb_funcall_argv(mrb, obj, m_sym, 1, &obj); // Calling ruby function from test.rb. + * mrb_funcall_argv(mrb, obj, MRB_SYM(method_name), 1, &obj); // Calling ruby function from test.rb. * fclose(fp); * mrb_close(mrb); * } @@ -1064,7 +1076,7 @@ MRB_API mrb_value mrb_funcall_argv(mrb_state *mrb, mrb_value val, mrb_sym name, */ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym name, mrb_int argc, const mrb_value *argv, mrb_value block); /** - * Create a symbol + * Create a symbol from C string. But usually it's better to use MRB_SYM(sym) and MRB_QSYM(qsym). * * Example: * @@ -1072,7 +1084,9 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym * :pizza # => :pizza * * // C style: - * mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); // => :pizza + * mrb_sym sym1 = mrb_intern_lit(mrb, "pizza"); // => :pizza + * mrb_sym sym2 = MRB_SYM(pizza); // => :pizza + * mrb_sym sym3 = MRB_SYM(pizza_p); // => :pizza? * * @param mrb The current mruby state. * @param str The string to be symbolized @@ -1081,8 +1095,14 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym MRB_API mrb_sym mrb_intern_cstr(mrb_state *mrb, const char* str); MRB_API mrb_sym mrb_intern(mrb_state*,const char*,size_t); MRB_API mrb_sym mrb_intern_static(mrb_state*,const char*,size_t); -#define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, lit, mrb_strlen_lit(lit)) +#define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, (lit ""), mrb_strlen_lit(lit)) MRB_API mrb_sym mrb_intern_str(mrb_state*,mrb_value); +/* mrb_intern_check series functions returns 0 if the symbol is not defined */ +MRB_API mrb_sym mrb_intern_check_cstr(mrb_state*,const char*); +MRB_API mrb_sym mrb_intern_check(mrb_state*,const char*,size_t); +MRB_API mrb_sym mrb_intern_check_str(mrb_state*,mrb_value); +/* mrb_check_intern series functions returns nil if the symbol is not defined */ +/* otherwise returns mrb_value */ MRB_API mrb_value mrb_check_intern_cstr(mrb_state*,const char*); MRB_API mrb_value mrb_check_intern(mrb_state*,const char*,size_t); MRB_API mrb_value mrb_check_intern_str(mrb_state*,mrb_value); @@ -1180,9 +1200,9 @@ MRB_API void mrb_close(mrb_state *mrb); MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*); MRB_API mrb_value mrb_top_self(mrb_state *mrb); -MRB_API mrb_value mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep); -MRB_API mrb_value mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep); -MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *iseq); +MRB_API mrb_value mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int stack_keep); +MRB_API mrb_value mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int stack_keep); +MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *iseq); /* compatibility macros */ #define mrb_toplevel_run_keep(m,p,k) mrb_top_run((m),(p),mrb_top_self(m),(k)) #define mrb_toplevel_run(m,p) mrb_toplevel_run_keep((m),(p),0) @@ -1197,7 +1217,7 @@ MRB_API mrb_bool mrb_obj_equal(mrb_state *mrb, mrb_value a, mrb_value b); MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2); MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base); MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val); -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val); #endif MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); @@ -1230,12 +1250,15 @@ MRB_API void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic* } while (0) MRB_API void mrb_write_barrier(mrb_state *, struct RBasic*); -MRB_API mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method); +MRB_API mrb_value mrb_type_convert(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method); +#define mrb_convert_type(mrb, val, type, tname, method) mrb_type_convert(mrb, val, type, mrb_intern_lit(mrb, method)) +MRB_API mrb_value mrb_type_convert_check(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method); +#define mrb_check_convert_type(mrb, val, type, tname, method) mrb_type_convert_check(mrb, val, type, mrb_intern_lit(mrb, method)) + MRB_API mrb_value mrb_any_to_s(mrb_state *mrb, mrb_value obj); MRB_API const char * mrb_obj_classname(mrb_state *mrb, mrb_value obj); MRB_API struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj); MRB_API mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c); -MRB_API mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method); MRB_API mrb_bool mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c); MRB_API mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self); MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self); @@ -1276,25 +1299,26 @@ MRB_API mrb_value mrb_vformat(mrb_state *mrb, const char *format, va_list ap); + those E_* macros requires mrb_state* variable named mrb. + exception objects obtained from those macros are local to mrb */ -#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_FROZEN_ERROR (mrb_exc_get(mrb, "FrozenError")) - -#define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError")) -#ifndef MRB_WITHOUT_FLOAT -#define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError")) +#define E_RUNTIME_ERROR (mrb_exc_get_id(mrb, MRB_SYM(RuntimeError))) +#define E_TYPE_ERROR (mrb_exc_get_id(mrb, MRB_SYM(TypeError))) +#define E_ZERODIV_ERROR (mrb_exc_get_id(mrb, MRB_SYM(ZeroDivisionError))) +#define E_ARGUMENT_ERROR (mrb_exc_get_id(mrb, MRB_SYM(ArgumentError))) +#define E_INDEX_ERROR (mrb_exc_get_id(mrb, MRB_SYM(IndexError))) +#define E_RANGE_ERROR (mrb_exc_get_id(mrb, MRB_SYM(RangeError))) +#define E_NAME_ERROR (mrb_exc_get_id(mrb, MRB_SYM(NameError))) +#define E_NOMETHOD_ERROR (mrb_exc_get_id(mrb, MRB_SYM(NoMethodError))) +#define E_SCRIPT_ERROR (mrb_exc_get_id(mrb, MRB_SYM(ScriptError))) +#define E_SYNTAX_ERROR (mrb_exc_get_id(mrb, MRB_SYM(SyntaxError))) +#define E_LOCALJUMP_ERROR (mrb_exc_get_id(mrb, MRB_SYM(LocalJumpError))) +#define E_REGEXP_ERROR (mrb_exc_get_id(mrb, MRB_SYM(RegexpError))) +#define E_FROZEN_ERROR (mrb_exc_get_id(mrb, MRB_SYM(FrozenError))) + +#define E_NOTIMP_ERROR (mrb_exc_get_id(mrb, MRB_SYM(NotImplementedError))) +#ifndef MRB_NO_FLOAT +#define E_FLOATDOMAIN_ERROR (mrb_exc_get_id(mrb, MRB_SYM(FloatDomainError))) #endif -#define E_KEY_ERROR (mrb_exc_get(mrb, "KeyError")) +#define E_KEY_ERROR (mrb_exc_get_id(mrb, MRB_SYM(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); @@ -1313,7 +1337,7 @@ MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj); MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj); MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val); -#define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val)) +#define mrb_int(mrb, val) mrb_integer(mrb_to_int(mrb, val)) /* string type checking (contrary to the name, it doesn't convert) */ MRB_API mrb_value mrb_to_str(mrb_state *mrb, mrb_value val); MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); @@ -1324,6 +1348,7 @@ MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o) } MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *c, const char *a, const char *b); +MRB_API void mrb_define_alias_id(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b); MRB_API const char *mrb_class_name(mrb_state *mrb, struct RClass* klass); MRB_API void mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val); @@ -1360,7 +1385,7 @@ MRB_API mrb_value mrb_fiber_alive_p(mrb_state *mrb, mrb_value fib); * * Implemented in mruby-fiber */ -#define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError")) +#define E_FIBER_ERROR (mrb_exc_get_id(mrb, MRB_SYM(FiberError))) MRB_API void mrb_stack_extend(mrb_state*, mrb_int); /* memory pool implementation */ diff --git a/include/mruby/array.h b/include/mruby/array.h index 92c86a8c5..5164efa69 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -21,7 +21,14 @@ typedef struct mrb_shared_array { mrb_value *ptr; } mrb_shared_array; -#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value))) +#if defined(MRB_32BIT) && defined(MRB_NO_BOXING) +# define MRB_ARY_NO_EMBED +# define MRB_ARY_EMBED_LEN_MAX 0 +#else +# define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value))) +mrb_static_assert(MRB_ARY_EMBED_LEN_MAX > 0, "MRB_ARY_EMBED_LEN_MAX > 0"); +#endif + struct RArray { MRB_OBJECT_HEADER; union { @@ -33,7 +40,9 @@ struct RArray { } aux; mrb_value *ptr; } heap; - void *ary[3]; +#ifndef MRB_ARY_NO_EMBED + mrb_value ary[MRB_ARY_EMBED_LEN_MAX]; +#endif } as; }; @@ -41,13 +50,21 @@ struct RArray { #define mrb_ary_value(p) mrb_obj_value((void*)(p)) #define RARRAY(v) ((struct RArray*)(mrb_ptr(v))) +#ifdef MRB_ARY_NO_EMBED +#define ARY_EMBED_P(a) 0 +#define ARY_UNSET_EMBED_FLAG(a) (void)0 +#define ARY_EMBED_LEN(a) 0 +#define ARY_SET_EMBED_LEN(a,len) (void)0 +#define ARY_EMBED_PTR(a) 0 +#else #define MRB_ARY_EMBED_MASK 7 #define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK) #define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK)) #define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1)) #define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1)) -#define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as.ary)) - +#define ARY_EMBED_PTR(a) ((a)->as.ary) +#endif + #define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len) #define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr) #define RARRAY_LEN(a) ARY_LEN(RARRAY(a)) diff --git a/include/mruby/boxing_nan.h b/include/mruby/boxing_nan.h index fae3b7630..3a99aeca6 100644 --- a/include/mruby/boxing_nan.h +++ b/include/mruby/boxing_nan.h @@ -7,12 +7,12 @@ #ifndef MRUBY_BOXING_NAN_H #define MRUBY_BOXING_NAN_H -#ifdef MRB_USE_FLOAT -# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<---- +#ifdef MRB_USE_FLOAT32 +# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT32 conflict <<---- #endif -#ifdef MRB_WITHOUT_FLOAT -# error ---->> MRB_NAN_BOXING and MRB_WITHOUT_FLOAT conflict <<---- +#ifdef MRB_NO_FLOAT +# error ---->> MRB_NAN_BOXING and MRB_NO_FLOAT conflict <<---- #endif #ifdef MRB_INT64 @@ -30,76 +30,91 @@ * In order to get enough bit size to save TT, all pointers are shifted 2 bits * in the right direction. Also, TTTTTT is the mrb_vtype + 1; */ -typedef struct mrb_value { - union { - mrb_float f; - union { - void *p; - struct { - MRB_ENDIAN_LOHI( - uint32_t ttt; - ,union { - mrb_int i; - mrb_sym sym; - }; - ) - }; +typedef uint64_t mrb_value; + +union mrb_value_ { + mrb_float f; + uint64_t u; #ifdef MRB_64BIT - struct RCptr *vp; + void *p; #endif - } value; + struct { + MRB_ENDIAN_LOHI( + uint32_t ttt; + ,uint32_t i; + ) }; -} mrb_value; +}; -#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f) +static inline union mrb_value_ +mrb_val_union(mrb_value v) +{ + union mrb_value_ x; + x.u = v; + return x; +} -#define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1) -#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_fixnum(o) (o).value.i -#define mrb_symbol(o) (o).value.sym +#define mrb_tt(o) ((enum mrb_vtype)((mrb_val_union(o).ttt & 0xfc000)>>14)-1) +#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < mrb_val_union(o).ttt ? mrb_tt(o) : MRB_TT_FLOAT) +#define mrb_float(o) mrb_val_union(o).f +#define mrb_fixnum(o) ((mrb_int)mrb_val_union(o).i) +#define mrb_integer(o) mrb_fixnum(o) +#define mrb_symbol(o) ((mrb_sym)mrb_val_union(o).i) #ifdef MRB_64BIT -MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*); +#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)(mrb_val_union(o).p)))<<2)) #define mrb_cptr(o) (((struct RCptr*)mrb_ptr(o))->p) #define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff) #else -#define mrb_cptr(o) ((o).value.p) +#define mrb_ptr(o) ((void*)mrb_val_union(o).i) +#define mrb_cptr(o) mrb_ptr(o) #define BOXNAN_SHIFT_LONG_POINTER(v) 0 #endif -#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\ - (o).attr = (v);\ - (o).value.ttt = 0xfff00000 | (((tt)+1)<<14);\ +#define BOXNAN_SET_VALUE(o, tt, attr, v) do { \ + union mrb_value_ mrb_value_union_variable; \ + mrb_value_union_variable.attr = (v);\ + mrb_value_union_variable.ttt = 0xfff00000 | (((tt)+1)<<14);\ + o = mrb_value_union_variable.u;\ } while (0) +#ifdef MRB_64BIT #define BOXNAN_SET_OBJ_VALUE(o, tt, v) do {\ - (o).value.p = (void*)((uintptr_t)(v)>>2);\ - (o).value.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\ + union mrb_value_ mrb_value_union_variable;\ + mrb_value_union_variable.p = (void*)((uintptr_t)(v)>>2);\ + mrb_value_union_variable.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\ + o = mrb_value_union_variable.u;\ } while (0) +#else +#define BOXNAN_SET_OBJ_VALUE(o, tt, v) BOXNAN_SET_VALUE(o, tt, i, (uint32_t)v) +#endif #define SET_FLOAT_VALUE(mrb,r,v) do { \ - if ((v) != (v)) { \ - (r).value.ttt = 0x7ff80000; \ - (r).value.i = 0; \ + union mrb_value_ mrb_value_union_variable; \ + if ((v) != (v)) { /* NaN */ \ + mrb_value_union_variable.ttt = 0x7ff80000; \ + mrb_value_union_variable.i = 0; \ } \ else { \ - (r).f = v; \ - }} while(0) + mrb_value_union_variable.f = (v); \ + } \ + r = mrb_value_union_variable.u; \ +} while(0) -#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 0) -#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 1) -#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, value.i, 1) -#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1) -#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n)) -#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) +#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 0) +#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 1) +#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, i, 1) +#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, i, 1) +#define SET_INT_VALUE(mrb, r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n)) +#define SET_FIXNUM_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n)) +#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, i, (uint32_t)(v)) #define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v)) #ifdef MRB_64BIT +MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*); #define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_nan_boxing_cptr_value(mrb, v)) #else -#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v) +#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, p, v) #endif -#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0) +#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, i, 0) #endif /* MRUBY_BOXING_NAN_H */ diff --git a/include/mruby/boxing_no.h b/include/mruby/boxing_no.h index 7573428e6..0b14590d9 100644 --- a/include/mruby/boxing_no.h +++ b/include/mruby/boxing_no.h @@ -11,7 +11,7 @@ #define MRB_SYMBOL_SHIFT 0 union mrb_value_union { -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT mrb_float f; #endif void *p; @@ -24,16 +24,13 @@ typedef struct mrb_value { enum mrb_vtype tt; } mrb_value; -#ifndef MRB_WITHOUT_FLOAT -#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f) -#endif - #define mrb_ptr(o) (o).value.p #define mrb_cptr(o) mrb_ptr(o) -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT #define mrb_float(o) (o).value.f #endif #define mrb_fixnum(o) (o).value.i +#define mrb_integer(o) mrb_fixnum(o) #define mrb_symbol(o) (o).value.sym #define mrb_type(o) (o).tt @@ -46,8 +43,9 @@ typedef struct mrb_value { #define SET_FALSE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 1) #define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1) #define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1) -#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n)) -#ifndef MRB_WITHOUT_FLOAT +#define SET_INT_VALUE(mrb,r,n) BOXNIX_SET_VALUE(r, MRB_TT_INTEGER, value.i, (n)) +#define SET_FIXNUM_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_INTEGER, value.i, (n)) +#ifndef MRB_NO_FLOAT #define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v)) #endif #define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) diff --git a/include/mruby/boxing_word.h b/include/mruby/boxing_word.h index 1b7815b7f..d7b5ff990 100644 --- a/include/mruby/boxing_word.h +++ b/include/mruby/boxing_word.h @@ -11,13 +11,18 @@ #error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode. #endif -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT struct RFloat { MRB_OBJECT_HEADER; mrb_float f; }; #endif +struct RInteger { + MRB_OBJECT_HEADER; + mrb_int i; +}; + enum mrb_special_consts { MRB_Qnil = 0, MRB_Qfalse = 4, @@ -47,13 +52,13 @@ enum mrb_special_consts { #define BOXWORD_IMMEDIATE_MASK 0x07 #define BOXWORD_SHIFT_VALUE(o,n,t) \ - (t)(((long)(o).w) >> BOXWORD_##n##_SHIFT) + (t)(((intptr_t)(o)) >> BOXWORD_##n##_SHIFT) #define BOXWORD_SET_SHIFT_VALUE(o,n,v) \ - ((o).w = (((unsigned long)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG) + ((o) = (((uintptr_t)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG) #define BOXWORD_SHIFT_VALUE_P(o,n) \ - (((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG) + (((o) & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG) #define BOXWORD_OBJ_TYPE_P(o,n) \ - (!mrb_immediate_p(o) && (o).value.bp->tt == MRB_TT_##n) + (!mrb_immediate_p(o) && mrb_val_union(o).bp->tt == MRB_TT_##n) /* * mrb_value representation: @@ -66,62 +71,74 @@ enum mrb_special_consts { * symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU) * object: ...PPPP P000 (any bits are 1) */ -typedef union mrb_value { - union { - void *p; +typedef uintptr_t mrb_value; +union mrb_value_ { + void *p; #ifdef MRB_64BIT - /* use struct to avoid bit shift. */ - struct { - MRB_ENDIAN_LOHI( - mrb_sym sym; - ,uint32_t sym_flag; - ) - }; + /* use struct to avoid bit shift. */ + struct { + MRB_ENDIAN_LOHI( + mrb_sym sym; + ,uint32_t sym_flag; + ) + }; #endif - struct RBasic *bp; -#ifndef MRB_WITHOUT_FLOAT - struct RFloat *fp; + struct RBasic *bp; +#ifndef MRB_NO_FLOAT + struct RFloat *fp; #endif - struct RCptr *vp; - } value; - unsigned long w; -} mrb_value; + struct RInteger *ip; + struct RCptr *vp; + uintptr_t w; +}; + +static inline union mrb_value_ +mrb_val_union(mrb_value v) +{ + union mrb_value_ x; + x.w = v; + return x; +} MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*); -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float); -MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); #endif +MRB_API mrb_value mrb_word_boxing_int_value(struct mrb_state*, mrb_int); -#ifndef MRB_WITHOUT_FLOAT -#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f) -#endif +#define mrb_immediate_p(o) ((o) & BOXWORD_IMMEDIATE_MASK || (o) == MRB_Qnil) -#define mrb_ptr(o) (o).value.p -#define mrb_cptr(o) (o).value.vp->p -#ifndef MRB_WITHOUT_FLOAT -#define mrb_float(o) (o).value.fp->f +#define mrb_ptr(o) mrb_val_union(o).p +#define mrb_cptr(o) mrb_val_union(o).vp->p +#ifndef MRB_NO_FLOAT +#define mrb_float(o) mrb_val_union(o).fp->f #endif #define mrb_fixnum(o) BOXWORD_SHIFT_VALUE(o, FIXNUM, mrb_int) +MRB_INLINE mrb_int +mrb_integer_func(mrb_value o) { + if (mrb_immediate_p(o)) return mrb_fixnum(o); + return mrb_val_union(o).ip->i; +} +#define mrb_integer(o) mrb_integer_func(o) #ifdef MRB_64BIT -#define mrb_symbol(o) (o).value.sym +#define mrb_symbol(o) mrb_val_union(o).sym #else #define mrb_symbol(o) BOXWORD_SHIFT_VALUE(o, SYMBOL, mrb_sym) #endif -#define mrb_bool(o) (((o).w & ~(unsigned long)MRB_Qfalse) != 0) +#define mrb_bool(o) (((o) & ~(unsigned long)MRB_Qfalse) != 0) -#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil) #define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM) +#define mrb_integer_p(o) (BOXWORD_SHIFT_VALUE_P(o, FIXNUM)||BOXWORD_OBJ_TYPE_P(o, INTEGER)) #ifdef MRB_64BIT -#define mrb_symbol_p(o) ((o).value.sym_flag == BOXWORD_SYMBOL_FLAG) +#define mrb_symbol_p(o) (mrb_val_union(o).sym_flag == BOXWORD_SYMBOL_FLAG) #else #define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL) #endif -#define mrb_undef_p(o) ((o).w == MRB_Qundef) -#define mrb_nil_p(o) ((o).w == MRB_Qnil) -#define mrb_false_p(o) ((o).w == MRB_Qfalse) -#define mrb_true_p(o) ((o).w == MRB_Qtrue) -#ifndef MRB_WITHOUT_FLOAT +#define mrb_undef_p(o) ((o) == MRB_Qundef) +#define mrb_nil_p(o) ((o) == MRB_Qnil) +#define mrb_false_p(o) ((o) == MRB_Qfalse) +#define mrb_true_p(o) ((o) == MRB_Qtrue) +#ifndef MRB_NO_FLOAT #define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT) #endif #define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY) @@ -143,32 +160,38 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); #define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT) #define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK) -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT #define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v)) #endif #define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v)) -#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef) -#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil) -#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse) -#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue) +#define SET_UNDEF_VALUE(r) ((r) = MRB_Qundef) +#define SET_NIL_VALUE(r) ((r) = MRB_Qnil) +#define SET_FALSE_VALUE(r) ((r) = MRB_Qfalse) +#define SET_TRUE_VALUE(r) ((r) = MRB_Qtrue) #define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r)) -#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n) +#define SET_INT_VALUE(mrb,r,n) ((r) = mrb_word_boxing_int_value(mrb, n)) +#define SET_FIXNUM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n) #ifdef MRB_64BIT -#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = BOXWORD_SYMBOL_FLAG) +#define SET_SYM_VALUE(r,v) do {\ + union mrb_value_ mrb_value_union_variable;\ + mrb_value_union_variable.sym = v;\ + mrb_value_union_variable.sym_flag = BOXWORD_SYMBOL_FLAG;\ + (r) = mrb_value_union_variable.w;\ +} while (0) #else #define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n) #endif -#define SET_OBJ_VALUE(r,v) ((r).value.p = v) +#define SET_OBJ_VALUE(r,v) ((r) = (uintptr_t)v) MRB_INLINE enum mrb_vtype mrb_type(mrb_value o) { return !mrb_bool(o) ? MRB_TT_FALSE : mrb_true_p(o) ? MRB_TT_TRUE : - mrb_fixnum_p(o) ? MRB_TT_FIXNUM : + mrb_fixnum_p(o) ? MRB_TT_INTEGER : mrb_symbol_p(o) ? MRB_TT_SYMBOL : mrb_undef_p(o) ? MRB_TT_UNDEF : - o.value.bp->tt; + mrb_val_union(o).bp->tt; } #endif /* MRUBY_BOXING_WORD_H */ diff --git a/include/mruby/class.h b/include/mruby/class.h index cbf96fef2..c88079e59 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -17,7 +17,7 @@ MRB_BEGIN_DECL struct RClass { MRB_OBJECT_HEADER; struct iv_tbl *iv; - struct kh_mt *mt; + struct mt_tbl *mt; struct RClass *super; }; @@ -35,9 +35,9 @@ mrb_class(mrb_state *mrb, mrb_value v) return mrb->true_class; case MRB_TT_SYMBOL: return mrb->symbol_class; - case MRB_TT_FIXNUM: - return mrb->fixnum_class; -#ifndef MRB_WITHOUT_FLOAT + case MRB_TT_INTEGER: + return mrb->integer_class; +#ifndef MRB_NO_FLOAT case MRB_TT_FLOAT: return mrb->float_class; #endif @@ -73,13 +73,11 @@ mrb_class(mrb_state *mrb, mrb_value v) #define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt))) #define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK) -MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*); -MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym); struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t); -MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec); MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b); +MRB_API void mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym sym); MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym); MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym); @@ -95,12 +93,17 @@ void mrb_gc_mark_mt(mrb_state*, struct RClass*); size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); void mrb_gc_free_mt(mrb_state*, struct RClass*); -#ifdef MRB_METHOD_CACHE +#ifndef MRB_NO_METHOD_CACHE void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c); #else #define mrb_mc_clear_by_class(mrb,c) #endif +/* return non zero to break the loop */ +struct mt_elem; +typedef int (mrb_mt_foreach_func)(mrb_state*,mrb_sym,struct mt_elem*,void*); +MRB_API void mrb_mt_foreach(mrb_state*, struct RClass*, mrb_mt_foreach_func*, void*); + MRB_END_DECL #endif /* MRUBY_CLASS_H */ diff --git a/include/mruby/compile.h b/include/mruby/compile.h index e8ab91eb9..36adf5a32 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -33,7 +33,7 @@ typedef struct mrbc_context { mrb_bool no_exec:1; mrb_bool keep_lv:1; mrb_bool no_optimize:1; - struct RProc *upper; + const struct RProc *upper; size_t parser_nerr; } mrbc_context; @@ -153,7 +153,7 @@ struct mrb_parser_state { mrb_bool no_optimize:1; mrb_bool capture_errors:1; - struct RProc *upper; + const struct RProc *upper; struct mrb_parser_message error_buffer[10]; struct mrb_parser_message warn_buffer[10]; diff --git a/include/mruby/debug.h b/include/mruby/debug.h index 5c5d56924..f22c7c77b 100644 --- a/include/mruby/debug.h +++ b/include/mruby/debug.h @@ -46,7 +46,7 @@ typedef struct mrb_irep_debug_info { * get line from irep's debug info and program counter * @return returns NULL if not found */ -MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc); +MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t pc); /* * get line from irep's debug info and program counter diff --git a/include/mruby/dump.h b/include/mruby/dump.h index db3e287d3..90eaca184 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -18,10 +18,11 @@ MRB_BEGIN_DECL #define DUMP_DEBUG_INFO 1 -int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); +int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); #ifndef MRB_DISABLE_STDIO -int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*); -int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, uint8_t flags, FILE *f, const char *initname); +int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*); +int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); +int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); mrb_irep *mrb_read_irep_file(mrb_state*, FILE*); MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*); MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*); @@ -48,11 +49,16 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t); /* Rite Binary File header */ #define RITE_BINARY_IDENT "RITE" -#define RITE_BINARY_FORMAT_VER "0007" +/* Binary Format Version Major:Minor */ +/* Major: Incompatible to prior versions */ +/* Minor: Upper-compatible to prior versions */ +#define RITE_BINARY_MAJOR_VER "01" +#define RITE_BINARY_MINOR_VER "00" +#define RITE_BINARY_FORMAT_VER RITE_BINARY_MAJOR_VER RITE_BINARY_MINOR_VER #define RITE_COMPILER_NAME "MATZ" #define RITE_COMPILER_VERSION "0000" -#define RITE_VM_VER "0002" +#define RITE_VM_VER "0300" #define RITE_BINARY_EOF "END\0" #define RITE_SECTION_IREP_IDENT "IREP" @@ -65,7 +71,8 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t); /* binary header */ struct rite_binary_header { uint8_t binary_ident[4]; /* Binary Identifier */ - uint8_t binary_version[4]; /* Binary Format Version */ + uint8_t major_version[2]; /* Binary Format Major Version */ + uint8_t minor_version[2]; /* Binary Format Minor Version */ uint8_t binary_crc[2]; /* Binary CRC */ uint8_t binary_size[4]; /* Binary Size */ uint8_t compiler_name[4]; /* Compiler name */ @@ -126,16 +133,6 @@ uint32_to_bin(uint32_t l, uint8_t *bin) return sizeof(uint32_t); } -static inline size_t -uint32l_to_bin(uint32_t l, uint8_t *bin) -{ - bin[3] = (l >> 24) & 0xff; - bin[2] = (l >> 16) & 0xff; - bin[1] = (l >> 8) & 0xff; - bin[0] = l & 0xff; - return sizeof(uint32_t); -} - static inline uint32_t bin_to_uint32(const uint8_t *bin) { @@ -145,15 +142,6 @@ bin_to_uint32(const uint8_t *bin) (uint32_t)bin[3]; } -static inline uint32_t -bin_to_uint32l(const uint8_t *bin) -{ - return (uint32_t)bin[3] << 24 | - (uint32_t)bin[2] << 16 | - (uint32_t)bin[1] << 8 | - (uint32_t)bin[0]; -} - static inline uint16_t bin_to_uint16(const uint8_t *bin) { diff --git a/include/mruby/endian.h b/include/mruby/endian.h new file mode 100644 index 000000000..477f3bc94 --- /dev/null +++ b/include/mruby/endian.h @@ -0,0 +1,44 @@ +/** +** @file mruby/endian.h - detect endian-ness +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_ENDIAN_H +#define MRUBY_ENDIAN_H + +#include <limits.h> + +MRB_BEGIN_DECL + +#if !defined(BYTE_ORDER) && defined(__BYTE_ORDER__) +# define BYTE_ORDER __BYTE_ORDER__ +#endif +#if !defined(BIG_ENDIAN) && defined(__ORDER_BIG_ENDIAN__) +# define BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#endif +#if !defined(LITTLE_ENDIAN) && defined(__ORDER_LITTLE_ENDIAN__) +# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#endif + +#ifdef BYTE_ORDER +# if BYTE_ORDER == BIG_ENDIAN +# define littleendian 0 +# elif BYTE_ORDER == LITTLE_ENDIAN +# define littleendian 1 +# endif +#endif +#ifndef littleendian +/* can't distinguish endian in compile time */ +static inline int +check_little_endian(void) +{ + unsigned int n = 1; + return (*(unsigned char *)&n == 1); +} +# define littleendian check_little_endian() +#endif + +MRB_END_DECL + +#endif /* MRUBY_ENDIAN_H */ diff --git a/include/mruby/error.h b/include/mruby/error.h index d24b5b0c3..9ad115f4b 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -23,7 +23,8 @@ struct RException { MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg); MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str); -#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) +#define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) +#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str_lit(mrb, c, lit) MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv); MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb); @@ -32,10 +33,10 @@ MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_va /* declaration for `fail` method */ MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); -#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING) +#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING) struct RBreak { MRB_OBJECT_HEADER; - struct RProc *proc; + const struct RProc *proc; mrb_value val; }; #define mrb_break_value_get(brk) ((brk)->val) @@ -43,7 +44,7 @@ struct RBreak { #else struct RBreak { MRB_OBJECT_HEADER; - struct RProc *proc; + const struct RProc *proc; union mrb_value_union value; }; #define RBREAK_VALUE_TT_MASK ((1 << 8) - 1) @@ -62,10 +63,43 @@ mrb_break_value_set(struct RBreak *brk, mrb_value val) brk->flags &= ~RBREAK_VALUE_TT_MASK; brk->flags |= val.tt; } -#endif /* MRB_64BIT || MRB_USE_FLOAT || MRB_NAN_BOXING || MRB_WORD_BOXING */ +#endif /* MRB_64BIT || MRB_USE_FLOAT32 || MRB_NAN_BOXING || MRB_WORD_BOXING */ #define mrb_break_proc_get(brk) ((brk)->proc) #define mrb_break_proc_set(brk, p) ((brk)->proc = p) +#define RBREAK_TAG_FOREACH(f) \ + f(RBREAK_TAG_BREAK, 0) \ + f(RBREAK_TAG_BREAK_UPPER, 1) \ + f(RBREAK_TAG_BREAK_INTARGET, 2) \ + f(RBREAK_TAG_RETURN_BLOCK, 3) \ + f(RBREAK_TAG_RETURN, 4) \ + f(RBREAK_TAG_RETURN_TOPLEVEL, 5) \ + f(RBREAK_TAG_JUMP, 6) \ + f(RBREAK_TAG_STOP, 7) + +#define RBREAK_TAG_DEFINE(tag, i) tag = i, +enum { + RBREAK_TAG_FOREACH(RBREAK_TAG_DEFINE) +}; +#undef RBREAK_TAG_DEFINE + +#define RBREAK_TAG_BIT 3 +#define RBREAK_TAG_BIT_OFF 8 +#define RBREAK_TAG_MASK (~(~UINT32_C(0) << RBREAK_TAG_BIT)) + +static inline uint32_t +mrb_break_tag_get(struct RBreak *brk) +{ + return (brk->flags >> RBREAK_TAG_BIT_OFF) & RBREAK_TAG_MASK; +} + +static inline void +mrb_break_tag_set(struct RBreak *brk, uint32_t tag) +{ + brk->flags &= ~(RBREAK_TAG_MASK << RBREAK_TAG_BIT_OFF); + brk->flags |= (tag & RBREAK_TAG_MASK) << RBREAK_TAG_BIT_OFF; +} + /** * Protect * diff --git a/include/mruby/hash.h b/include/mruby/hash.h index 86fbe329d..7dab4a85c 100644 --- a/include/mruby/hash.h +++ b/include/mruby/hash.h @@ -201,7 +201,7 @@ MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2); /* RHASH_TBL allocates st_table if not available. */ #define RHASH(obj) ((struct RHash*)(mrb_ptr(obj))) #define RHASH_TBL(h) (RHASH(h)->ht) -#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone")) +#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), MRB_SYM(ifnone)) #define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h) #define MRB_HASH_DEFAULT 1 diff --git a/include/mruby/irep.h b/include/mruby/irep.h index 661ef2b48..a9c20681c 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -16,28 +16,58 @@ MRB_BEGIN_DECL enum irep_pool_type { - IREP_TT_STRING, - IREP_TT_FIXNUM, - IREP_TT_FLOAT, + IREP_TT_STR = 0, /* string (need free) */ + IREP_TT_SSTR = 2, /* string (static) */ + IREP_TT_INT32 = 1, /* 32bit integer */ + IREP_TT_INT64 = 3, /* 64bit integer */ + IREP_TT_FLOAT = 5, /* float (double/float) */ }; -struct mrb_locals { - mrb_sym name; - uint16_t r; +#define IREP_TT_NFLAG 1 /* number (non string) flag */ +#define IREP_TT_SFLAG 2 /* static string flag */ + +typedef struct mrb_pool_value { + uint32_t tt; /* packed type and length (for string) */ + union { + const char *str; + int32_t i32; +#ifdef MRB_64BIT + int64_t i64; +#endif + mrb_float f; + } u; +} mrb_pool_value; + +enum mrb_catch_type { + MRB_CATCH_RESCUE = 0, + MRB_CATCH_ENSURE = 1, +}; + +struct mrb_irep_catch_handler { + uint8_t type; /* enum mrb_catch_type */ + uint8_t begin[2]; /* The starting address to match the hander. Includes this. */ + uint8_t end[2]; /* The endpoint address that matches the hander. Not Includes this. */ + uint8_t target[2]; /* The address to jump to if a match is made. */ }; /* Program data array struct */ typedef struct mrb_irep { uint16_t nlocals; /* Number of local variables */ uint16_t nregs; /* Number of register variables */ + uint16_t clen; /* Number of catch handlers */ uint8_t flags; const mrb_code *iseq; - mrb_value *pool; - mrb_sym *syms; - struct mrb_irep **reps; - - struct mrb_locals *lv; + /* + * A catch handler table is placed after the iseq entity. + * The reason it doesn't add fields to the structure is to keep the mrb_irep structure from bloating. + * The catch handler table can be obtained with `mrb_irep_catch_handler_table(irep)`. + */ + const mrb_pool_value *pool; + const mrb_sym *syms; + const struct mrb_irep * const *reps; + + const mrb_sym *lv; /* debug info */ struct mrb_irep_debug_info* debug_info; @@ -46,6 +76,8 @@ typedef struct mrb_irep { } mrb_irep; #define MRB_ISEQ_NO_FREE 1 +#define MRB_IREP_NO_FREE 2 +#define MRB_IREP_STATIC (MRB_ISEQ_NO_FREE | MRB_IREP_NO_FREE) MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb); @@ -92,6 +124,17 @@ struct mrb_insn_data { struct mrb_insn_data mrb_decode_insn(const mrb_code *pc); +static inline const struct mrb_irep_catch_handler * +mrb_irep_catch_handler_table(const struct mrb_irep *irep) +{ + if (irep->clen > 0) { + return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen); + } + else { + return (const struct mrb_irep_catch_handler*)NULL; + } +} + MRB_END_DECL #endif /* MRUBY_IREP_H */ diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index 06a33cc6f..7e70b9dee 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -1,5 +1,5 @@ /** -** @file mruby/numeric.h - Numeric, Integer, Float, Fixnum class +** @file mruby/numeric.h - Numeric, Integer, Float class ** ** See Copyright Notice in mruby.h */ @@ -12,17 +12,17 @@ /** * Numeric class and it's sub-classes. * - * Integer, Float and Fixnum + * Integer and Float */ MRB_BEGIN_DECL -#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_INT_MAX) -#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_INT_MIN) +#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_FIXNUM_MAX) +#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_FIXNUM_MIN) #define TYPED_FIXABLE(f,t) (TYPED_POSFIXABLE(f,t) && TYPED_NEGFIXABLE(f,t)) #define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int) #define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int) #define FIXABLE(f) TYPED_FIXABLE(f,mrb_int) -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT #ifdef MRB_INT64 #define FIXABLE_FLOAT(f) ((f)>=-9223372036854775808.0 && (f)<9223372036854775808.0) #else @@ -30,16 +30,15 @@ MRB_BEGIN_DECL #endif #endif -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val); #endif MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base); /* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */ -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); MRB_API int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float f); MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x); -MRB_API mrb_value mrb_int_value(mrb_state *mrb, mrb_float f); #endif MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y); @@ -137,15 +136,15 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product) if (multiplicand > 0) { if (multiplier > MRB_INT_MAX / multiplicand) return TRUE; } - else { + else if (multiplicand < 0) { if (multiplicand < MRB_INT_MAX / multiplier) return TRUE; } } - else { + else if (multiplier < 0) { if (multiplicand > 0) { if (multiplier < MRB_INT_MAX / multiplicand) return TRUE; } - else { + else if (multiplicand < 0) { if (multiplier != 0 && multiplicand < MRB_INT_MAX / multiplier) return TRUE; } } @@ -161,13 +160,13 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product) #endif -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT # include <stdint.h> # include <float.h> # define MRB_FLT_RADIX FLT_RADIX -# ifdef MRB_USE_FLOAT +# ifdef MRB_USE_FLOAT32 # define MRB_FLT_MANT_DIG FLT_MANT_DIG # define MRB_FLT_EPSILON FLT_EPSILON # define MRB_FLT_DIG FLT_DIG @@ -178,7 +177,7 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product) # define MRB_FLT_MAX FLT_MAX # define MRB_FLT_MAX_10_EXP FLT_MAX_10_EXP -# else /* not MRB_USE_FLOAT */ +# else /* not MRB_USE_FLOAT32 */ # define MRB_FLT_MANT_DIG DBL_MANT_DIG # define MRB_FLT_EPSILON DBL_EPSILON # define MRB_FLT_DIG DBL_DIG @@ -188,8 +187,8 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product) # define MRB_FLT_MAX_EXP DBL_MAX_EXP # define MRB_FLT_MAX DBL_MAX # define MRB_FLT_MAX_10_EXP DBL_MAX_10_EXP -# endif /* MRB_USE_FLOAT */ -#endif /* MRB_WITHOUT_FLOAT */ +# endif /* MRB_USE_FLOAT32 */ +#endif /* MRB_NO_FLOAT */ MRB_END_DECL diff --git a/include/mruby/opcode.h b/include/mruby/opcode.h index 95e6736a4..a6c636cf8 100644 --- a/include/mruby/opcode.h +++ b/include/mruby/opcode.h @@ -39,31 +39,4 @@ enum mrb_insn { #define FETCH_S() do {a=READ_S();} while (0) #define FETCH_W() do {a=READ_W();} while (0) -/* with OP_EXT1 (1st 16bit) */ -#define FETCH_Z_1() FETCH_Z() -#define FETCH_B_1() FETCH_S() -#define FETCH_BB_1() do {a=READ_S(); b=READ_B();} while (0) -#define FETCH_BBB_1() do {a=READ_S(); b=READ_B(); c=READ_B();} while (0) -#define FETCH_BS_1() do {a=READ_S(); b=READ_S();} while (0) -#define FETCH_S_1() FETCH_S() -#define FETCH_W_1() FETCH_W() - -/* with OP_EXT2 (2nd 16bit) */ -#define FETCH_Z_2() FETCH_Z() -#define FETCH_B_2() FETCH_B() -#define FETCH_BB_2() do {a=READ_B(); b=READ_S();} while (0) -#define FETCH_BBB_2() do {a=READ_B(); b=READ_S(); c=READ_B();} while (0) -#define FETCH_BS_2() FETCH_BS() -#define FETCH_S_2() FETCH_S() -#define FETCH_W_2() FETCH_W() - -/* with OP_EXT3 (1st & 2nd 16bit) */ -#define FETCH_Z_3() FETCH_Z() -#define FETCH_B_3() FETCH_B() -#define FETCH_BB_3() do {a=READ_S(); b=READ_S();} while (0) -#define FETCH_BBB_3() do {a=READ_S(); b=READ_S(); c=READ_B();} while (0) -#define FETCH_BS_3() do {a=READ_S(); b=READ_S();} while (0) -#define FETCH_S_3() FETCH_S() -#define FETCH_W_3() FETCH_W() - #endif /* MRUBY_OPCODE_H */ diff --git a/include/mruby/ops.h b/include/mruby/ops.h index e85ee3133..75936a791 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -25,6 +25,7 @@ OPCODE(LOADI_4, B) /* R(a) = mrb_int(4) */ OPCODE(LOADI_5, B) /* R(a) = mrb_int(5) */ OPCODE(LOADI_6, B) /* R(a) = mrb_int(6) */ OPCODE(LOADI_7, B) /* R(a) = mrb_int(7) */ +OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */ OPCODE(LOADSYM, BB) /* R(a) = Syms(b) */ OPCODE(LOADNIL, B) /* R(a) = nil */ OPCODE(LOADSELF, B) /* R(a) = self */ @@ -48,13 +49,10 @@ OPCODE(JMP, S) /* pc=a */ OPCODE(JMPIF, BS) /* if R(a) pc=b */ OPCODE(JMPNOT, BS) /* if !R(a) pc=b */ OPCODE(JMPNIL, BS) /* if R(a)==nil pc=b */ -OPCODE(ONERR, S) /* rescue_push(a) */ +OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */ OPCODE(EXCEPT, B) /* R(a) = exc */ OPCODE(RESCUE, BB) /* R(b) = R(a).isa?(R(b)) */ -OPCODE(POPERR, B) /* a.times{rescue_pop()} */ -OPCODE(RAISE, B) /* raise(R(a)) */ -OPCODE(EPUSH, B) /* ensure_push(SEQ[a]) */ -OPCODE(EPOP, B) /* A.times{ensure_pop().call} */ +OPCODE(RAISEIF, B) /* raise(R(a)) if R(a) */ OPCODE(SENDV, BB) /* R(a) = call(R(a),Syms(b),*R(a+1)) */ OPCODE(SENDVB, BB) /* R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) */ OPCODE(SEND, BBB) /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) */ @@ -111,8 +109,4 @@ OPCODE(SCLASS, B) /* R(a) = R(a).singleton_class */ OPCODE(TCLASS, B) /* R(a) = target_class */ OPCODE(DEBUG, BBB) /* print a,b,c */ OPCODE(ERR, B) /* raise(LocalJumpError, Lit(a)) */ -OPCODE(EXT1, Z) /* make 1st operand 16bit */ -OPCODE(EXT2, Z) /* make 2nd operand 16bit */ -OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */ OPCODE(STOP, Z) /* stop VM */ -OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */ diff --git a/include/mruby/presym.h b/include/mruby/presym.h new file mode 100644 index 000000000..3cc12e8fb --- /dev/null +++ b/include/mruby/presym.h @@ -0,0 +1,25 @@ +/** +** @file mruby/presym.h - Preallocated Symbols +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_PRESYM_H +#define MRUBY_PRESYM_H + +#undef MRB_PRESYM_MAX +#define MRB_PRESYM_CSYM(sym, num) MRB_PRESYM__##sym = (num<<1), +#define MRB_PRESYM_QSYM(str, sym, num) MRB_PRESYM_q_##sym = (num<<1), +#define MRB_PRESYM_SYM(sym, num) + +enum mruby_presym { +#include <../build/presym.inc> +}; + +#undef MRB_PRESYM_CSYM +#undef MRB_PRESYM_QSYM +#undef MRB_PRESYM_SYM + +#define MRB_SYM(sym) MRB_PRESYM__##sym +#define MRB_QSYM(sym) MRB_PRESYM_q_##sym +#endif /* MRUBY_PRESYM_H */ diff --git a/include/mruby/proc.h b/include/mruby/proc.h index 12013c3ae..981e1111d 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -41,10 +41,10 @@ void mrb_env_unshare(mrb_state*, struct REnv*); struct RProc { MRB_OBJECT_HEADER; union { - mrb_irep *irep; + const mrb_irep *irep; mrb_func_t func; } body; - struct RProc *upper; + const struct RProc *upper; union { struct RClass *target_class; struct REnv *env; @@ -57,7 +57,7 @@ struct RProc { #define MRB_ASPEC_REST(a) (((a) >> 12) & 0x1) #define MRB_ASPEC_POST(a) (((a) >> 7) & 0x1f) #define MRB_ASPEC_KEY(a) (((a) >> 2) & 0x1f) -#define MRB_ASPEC_KDICT(a) ((a) & (1<<1)) +#define MRB_ASPEC_KDICT(a) (((a) >> 1) & 0x1) #define MRB_ASPEC_BLOCK(a) ((a) & 1) #define MRB_PROC_CFUNC_FL 128 @@ -86,16 +86,13 @@ struct RProc { #define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v))) -struct RProc *mrb_proc_new(mrb_state*, mrb_irep*); -struct RProc *mrb_closure_new(mrb_state*, mrb_irep*); +struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*); +struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*); MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t); MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals); void mrb_proc_copy(struct RProc *a, struct RProc *b); mrb_int mrb_proc_arity(const struct RProc *p); -/* implementation of #send method */ -mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); - /* following functions are defined in mruby-proc-ext so please include it when using */ MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv); MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); @@ -104,7 +101,8 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); #define MRB_METHOD_FUNC_FL 1 #define MRB_METHOD_NOARG_FL 2 -#ifndef MRB_METHOD_T_STRUCT + +#ifndef MRB_USE_METHOD_T_STRUCT #define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL) #define MRB_METHOD_NOARG_P(m) (((uintptr_t)(m))&MRB_METHOD_NOARG_FL) @@ -128,7 +126,7 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); #define MRB_METHOD_PROC(m) ((m).proc) #define MRB_METHOD_UNDEF_P(m) ((m).proc==NULL) -#endif /* MRB_METHOD_T_STRUCT */ +#endif /* MRB_USE_METHOD_T_STRUCT */ #define MRB_METHOD_CFUNC_P(m) (MRB_METHOD_FUNC_P(m)?TRUE:(MRB_METHOD_PROC(m)?(MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m))):FALSE)) #define MRB_METHOD_CFUNC(m) (MRB_METHOD_FUNC_P(m)?MRB_METHOD_FUNC(m):((MRB_METHOD_PROC(m)&&MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m)))?MRB_PROC_CFUNC(MRB_METHOD_PROC(m)):NULL)) @@ -137,6 +135,8 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); #include <mruby/khash.h> KHASH_DECLARE(mt, mrb_sym, mrb_method_t, TRUE) +MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc); + MRB_END_DECL #endif /* MRUBY_PROC_H */ diff --git a/include/mruby/string.h b/include/mruby/string.h index 93c94ef5d..8384128c7 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -35,7 +35,7 @@ struct RString { }; struct RStringEmbed { MRB_OBJECT_HEADER; - char ary[]; + char ary[RSTRING_EMBED_LEN_MAX+1]; }; #define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type) @@ -92,9 +92,6 @@ struct RStringEmbed { # define RSTR_COPY_ASCII_FLAG(dst, src) (void)0 #endif -#define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL) -#define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL) - /** * Returns a pointer from a Ruby string */ @@ -112,13 +109,11 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_FSHARED 2 #define MRB_STR_NOFREE 4 #define MRB_STR_EMBED 8 /* type flags up to here */ -#define MRB_STR_POOL 16 /* status flags from here */ -#define MRB_STR_ASCII 32 +#define MRB_STR_ASCII 16 #define MRB_STR_EMBED_LEN_SHIFT 6 #define MRB_STR_EMBED_LEN_BIT 5 #define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT) -#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1) - +#define MRB_STR_TYPE_MASK 15 void mrb_gc_free_str(mrb_state*, struct RString*); @@ -382,8 +377,9 @@ MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck) /** * Returns a converted string type. * For type checking, non converting `mrb_to_str` is recommended. + * obsolete: use `mrb_obj_as_string()` instead. */ -MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str); +#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str) /** * Returns true if the strings match and false if the strings don't match. @@ -447,7 +443,6 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2); */ MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str); -mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree); uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str); mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); diff --git a/include/mruby/throw.h b/include/mruby/throw.h index 1f1298d7d..b5ea7312e 100644 --- a/include/mruby/throw.h +++ b/include/mruby/throw.h @@ -13,7 +13,9 @@ # endif #endif -#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus) +#if defined(MRB_ENABLE_CXX_EXCEPTION) + +# if defined(__cplusplus) #define MRB_TRY(buf) try { #define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; } @@ -22,6 +24,10 @@ #define MRB_THROW(buf) throw((buf)->impl) typedef mrb_int mrb_jmpbuf_impl; +# else +# error "need to be compiled with C++ compiler" +# endif /* __cplusplus */ + #else #include <setjmp.h> @@ -46,9 +52,11 @@ typedef mrb_int mrb_jmpbuf_impl; struct mrb_jmpbuf { mrb_jmpbuf_impl impl; -#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus) +#if defined(MRB_ENABLE_CXX_EXCEPTION) static mrb_int jmpbuf_id; +# if defined(__cplusplus) mrb_jmpbuf() : impl(jmpbuf_id++) {} +# endif #endif }; diff --git a/include/mruby/value.h b/include/mruby/value.h index 473774b00..698c83300 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -54,16 +54,20 @@ struct mrb_state; #if defined(MRB_INT64) typedef int64_t mrb_int; # define MRB_INT_BIT 64 -# define MRB_INT_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT) -# define MRB_INT_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT) +# define MRB_INT_MIN INT64_MIN +# define MRB_INT_MAX INT64_MAX +# define MRB_FIXNUM_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT) +# define MRB_FIXNUM_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT) # define MRB_PRIo PRIo64 # define MRB_PRId PRId64 # define MRB_PRIx PRIx64 #else typedef int32_t mrb_int; # define MRB_INT_BIT 32 -# define MRB_INT_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT) -# define MRB_INT_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT) +# define MRB_INT_MIN INT32_MIN +# define MRB_INT_MAX INT32_MAX +# define MRB_FIXNUM_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT) +# define MRB_FIXNUM_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT) # define MRB_PRIo PRIo32 # define MRB_PRId PRId32 # define MRB_PRIx PRIx32 @@ -75,9 +79,9 @@ struct mrb_state; # define MRB_ENDIAN_LOHI(a,b) b a #endif -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT MRB_API double mrb_float_read(const char*, char**); -#ifdef MRB_USE_FLOAT +#ifdef MRB_USE_FLOAT32 typedef float mrb_float; #else typedef double mrb_float; @@ -90,7 +94,7 @@ MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list ar MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...); # define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg) # define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__) -# if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT +# if _MSC_VER < 1800 && !defined MRB_NO_FLOAT # include <float.h> # define isfinite(n) _finite(n) # define isnan _isnan @@ -106,7 +110,7 @@ enum mrb_vtype { MRB_TT_FALSE = 0, MRB_TT_TRUE, MRB_TT_FLOAT, - MRB_TT_FIXNUM, + MRB_TT_INTEGER, MRB_TT_SYMBOL, MRB_TT_UNDEF, MRB_TT_CPTR, @@ -130,6 +134,9 @@ enum mrb_vtype { MRB_TT_MAXDEFINE }; +/* for compatibility */ +#define MRB_TT_FIXNUM MRB_TT_INTEGER + #include <mruby/object.h> #ifdef MRB_DOCUMENTATION_BLOCK @@ -177,8 +184,11 @@ struct RCptr { #ifndef mrb_immediate_p #define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE) #endif +#ifndef mrb_integer_p +#define mrb_integer_p(o) (mrb_type(o) == MRB_TT_INTEGER) +#endif #ifndef mrb_fixnum_p -#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM) +#define mrb_fixnum_p(o) mrb_integer_p(o) #endif #ifndef mrb_symbol_p #define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL) @@ -195,7 +205,7 @@ struct RCptr { #ifndef mrb_true_p #define mrb_true_p(o) (mrb_type(o) == MRB_TT_TRUE) #endif -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT #ifndef mrb_float_p #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) #endif @@ -264,7 +274,7 @@ struct RCptr { * * Takes a float and boxes it into an mrb_value */ -#ifndef MRB_WITHOUT_FLOAT +#ifndef MRB_NO_FLOAT MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) { mrb_value v; @@ -284,14 +294,19 @@ mrb_cptr_value(struct mrb_state *mrb, void *p) } /** - * Returns a fixnum in Ruby. - * - * Takes an integer and boxes it into an mrb_value + * Returns an integer in Ruby. */ +MRB_INLINE mrb_value mrb_int_value(struct mrb_state *mrb, mrb_int i) +{ + mrb_value v; + SET_INT_VALUE(mrb, v, i); + return v; +} + MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i) { mrb_value v; - SET_INT_VALUE(v, i); + SET_FIXNUM_VALUE(v, i); return v; } |
