diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-07-17 10:35:41 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-07-17 10:35:41 +0900 |
| commit | d605b72c1d6fa4564a0a5e88535504b6850463b5 (patch) | |
| tree | 774fc0de56002abb3bb2b1c3387ff08f91876d17 /include | |
| parent | 2af92d0ebcbeca6d3d85a27c8193273080a63090 (diff) | |
| parent | 9af3b7c6258de327218dd04e69d76ae68caf17b1 (diff) | |
| download | mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.tar.gz mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.zip | |
Merge branch 'master' into i110/inspect-recursion
Diffstat (limited to 'include')
| -rw-r--r-- | include/mrbconf.h | 95 | ||||
| -rw-r--r-- | include/mruby.h | 98 | ||||
| -rw-r--r-- | include/mruby/array.h | 20 | ||||
| -rw-r--r-- | include/mruby/boxing_nan.h | 2 | ||||
| -rw-r--r-- | include/mruby/boxing_word.h | 56 | ||||
| -rw-r--r-- | include/mruby/class.h | 37 | ||||
| -rw-r--r-- | include/mruby/common.h | 17 | ||||
| -rw-r--r-- | include/mruby/compile.h | 19 | ||||
| -rw-r--r-- | include/mruby/data.h | 11 | ||||
| -rw-r--r-- | include/mruby/debug.h | 10 | ||||
| -rw-r--r-- | include/mruby/dump.h | 10 | ||||
| -rw-r--r-- | include/mruby/error.h | 2 | ||||
| -rw-r--r-- | include/mruby/hash.h | 65 | ||||
| -rw-r--r-- | include/mruby/irep.h | 33 | ||||
| -rw-r--r-- | include/mruby/istruct.h | 4 | ||||
| -rw-r--r-- | include/mruby/numeric.h | 10 | ||||
| -rw-r--r-- | include/mruby/object.h | 11 | ||||
| -rw-r--r-- | include/mruby/opcode.h | 186 | ||||
| -rw-r--r-- | include/mruby/ops.h | 117 | ||||
| -rw-r--r-- | include/mruby/proc.h | 17 | ||||
| -rw-r--r-- | include/mruby/range.h | 42 | ||||
| -rw-r--r-- | include/mruby/string.h | 62 | ||||
| -rw-r--r-- | include/mruby/throw.h | 8 | ||||
| -rw-r--r-- | include/mruby/value.h | 29 | ||||
| -rw-r--r-- | include/mruby/variable.h | 12 | ||||
| -rw-r--r-- | include/mruby/version.h | 26 |
26 files changed, 655 insertions, 344 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h index cc28acfaa..f5e8858ce 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -41,10 +41,15 @@ /* you might need to specify --falign-functions=n (where n>1) */ //#define MRB_METHOD_TABLE_INLINE -/* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT64 */ +/* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT32 and MRB_INT64 */ //#define MRB_INT16 -/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT16 */ +/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT16 and MRB_INT64; + Default for 32-bit CPU mode. */ +//#define MRB_INT32 + +/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT16 and MRB_INT32; + Default for 64-bit CPU mode. */ //#define MRB_INT64 /* if no specific integer type is chosen */ @@ -58,12 +63,20 @@ # endif #endif +#define MRB_COMPLEX_NUMBERS +#define MRB_RATIONAL_NUMBERS + +/* 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 -/* define on big endian machines; used by MRB_NAN_BOXING */ -//#define MRB_ENDIAN_BIG - /* represent mrb_value as a word (natural unit of data for the processor) */ //#define MRB_WORD_BOXING @@ -83,6 +96,11 @@ effective only when MRB_USE_ETEXT_EDATA is defined */ //#define MRB_NO_INIT_ARRAY_START +/* if do not works both MRB_USE_ETEXT_EDATA and MRB_NO_INIT_ARRAY_START, + you can try mrb_ro_data_p() that you have implemented yourself in any file; + prototype is `mrb_bool mrb_ro_data_p(const char *ptr)` */ +//#define MRB_USE_CUSTOM_RO_DATA_P + /* turn off generational GC by default */ //#define MRB_GC_TURN_OFF_GENERATIONAL @@ -115,6 +133,7 @@ /* -DMRB_ENABLE_XXXX to enable following features */ //#define MRB_ENABLE_DEBUG_HOOK /* hooks for debugger */ +//#define MRB_ENABLE_ALL_SYMBOLS /* Symbols.all_symbols */ /* end of configuration */ @@ -140,4 +159,70 @@ # define TRUE 1 #endif +/* +** mruby tuning profiles +**/ + +/* A profile for micro controllers */ +#if defined(MRB_CONSTRAINED_BASELINE_PROFILE) +# ifndef KHASH_DEFAULT_SIZE +# define KHASH_DEFAULT_SIZE 16 +# endif + +# ifndef MRB_STR_BUF_MIN_SIZE +# define MRB_STR_BUF_MIN_SIZE 32 +# endif + +# ifndef MRB_HEAP_PAGE_SIZE +# define MRB_HEAP_PAGE_SIZE 256 +# endif + +/* A profile for default mruby */ +#elif defined(MRB_BASELINE_PROFILE) + +/* 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 + +# ifndef MRB_METHOD_TABLE_INLINE +# define MRB_METHOD_TABLE_INLINE +# endif + +# ifndef MRB_IV_SEGMENT_SIZE +# define MRB_IV_SEGMENT_SIZE 32 +# endif + +# ifndef MRB_HEAP_PAGE_SIZE +# define MRB_HEAP_PAGE_SIZE 4096 +# endif + +/* 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 + +# ifndef MRB_METHOD_TABLE_INLINE +# define MRB_METHOD_TABLE_INLINE +# endif + +# ifndef MRB_IV_SEGMENT_SIZE +# define MRB_IV_SEGMENT_SIZE 64 +# endif + +# ifndef MRB_HEAP_PAGE_SIZE +# define MRB_HEAP_PAGE_SIZE 4096 +# endif +#endif + #endif /* MRUBYCONF_H */ diff --git a/include/mruby.h b/include/mruby.h index 3b953a327..7deb3cbe2 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1,7 +1,7 @@ /* ** mruby - An embeddable Ruby implementation ** -** Copyright (c) mruby developers 2010-2018 +** Copyright (c) mruby developers 2010-2019 ** ** Permission is hereby granted, free of charge, to any person obtaining ** a copy of this software and associated documentation files (the @@ -34,6 +34,7 @@ #define __STDC_FORMAT_MACROS #endif +#include <stdarg.h> #include <stdint.h> #include <stddef.h> #include <limits.h> @@ -57,7 +58,7 @@ #define mrb_assert_int_fit(t1,n,t2,max) ((void)0) #endif -#if __STDC_VERSION__ >= 201112L +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L #define mrb_static_assert(exp, str) _Static_assert(exp, str) #else #define mrb_static_assert(exp, str) mrb_assert(exp) @@ -83,7 +84,7 @@ #endif #endif -#include "mruby/common.h" +#include <mruby/common.h> #include <mruby/value.h> #include <mruby/gc.h> #include <mruby/version.h> @@ -93,7 +94,7 @@ */ MRB_BEGIN_DECL -typedef uint32_t mrb_code; +typedef uint8_t mrb_code; /** * Required arguments signature type. @@ -123,9 +124,8 @@ typedef struct { mrb_sym mid; struct RProc *proc; mrb_value *stackent; - int nregs; - int ridx; - int epos; + uint16_t ridx; + uint16_t epos; struct REnv *env; mrb_code *pc; /* return address */ mrb_code *err; /* error position */ @@ -152,10 +152,10 @@ struct mrb_context { mrb_callinfo *ci; mrb_callinfo *cibase, *ciend; - mrb_code **rescue; /* exception handler stack */ - int rsize; + uint16_t *rescue; /* exception handler stack */ + uint16_t rsize; struct RProc **ensure; /* ensure handler stack */ - int esize, eidx; + uint16_t esize, eidx; enum mrb_fiber_state status; mrb_bool vmexec; @@ -196,13 +196,9 @@ struct mrb_jmpbuf; typedef void (*mrb_atexit_func)(struct mrb_state*); -#define MRB_STATE_NO_REGEXP 1 -#define MRB_STATE_REGEXP 2 - typedef struct mrb_state { struct mrb_jmpbuf *jmp; - uint32_t flags; mrb_allocf allocf; /* memory allocation function */ void *allocf_ud; /* auxiliary data of allocf */ @@ -232,7 +228,6 @@ typedef struct mrb_state { struct RClass *symbol_class; struct RClass *kernel_module; - struct alloca_header *mems; mrb_gc gc; #ifdef MRB_METHOD_CACHE @@ -240,9 +235,12 @@ typedef struct mrb_state { #endif mrb_sym symidx; - struct kh_n2s *name2sym; /* symbol hash */ struct symbol_name *symtbl; /* symbol table */ + mrb_sym symhash[256]; size_t symcapa; +#ifndef MRB_ENABLE_SYMBOLL_ALL + char symbuf[8]; /* buffer for small symbol names */ +#endif #ifdef MRB_ENABLE_DEBUG_HOOK void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs); @@ -268,7 +266,8 @@ typedef struct mrb_state { #else mrb_atexit_func *atexit_stack; #endif - mrb_int atexit_stack_len; + uint16_t atexit_stack_len; + uint16_t ecall_nest; /* prevent infinite recursive ecall() */ } mrb_state; /** @@ -386,7 +385,7 @@ MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec); /** - * Defines a module fuction. + * Defines a module function. * * Example: * @@ -486,9 +485,10 @@ MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_ * } * @param [mrb_state*] mrb_state* The mruby state reference. * @param [struct RClass*] RClass* A class the method will be undefined from. - * @param [const char*] constchar* The name of the method to be undefined. + * @param [const char*] const char* The name of the method to be undefined. */ MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*); +MRB_API void mrb_undef_method_id(mrb_state*, struct RClass*, mrb_sym); /** * Undefine a class method. @@ -525,12 +525,12 @@ MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*); * } * @param [mrb_state*] mrb_state* The mruby state reference. * @param [RClass*] RClass* A class the class method will be undefined from. - * @param [constchar*] constchar* The name of the class method to be undefined. + * @param [const char*] const char* The name of the class method to be undefined. */ MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*); /** - * Initialize a new object instace of c class. + * Initialize a new object instance of c class. * * Example: * @@ -565,8 +565,6 @@ MRB_INLINE mrb_value mrb_class_new_instance(mrb_state *mrb, mrb_int argc, const return mrb_obj_new(mrb,c,argc,argv); } -MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); - /** * Creates a new instance of Class, Class. * @@ -704,6 +702,9 @@ 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); +/* a function to raise NotImplementedError with current method name */ +MRB_API void mrb_notimplement(mrb_state*); +/* a function to be replacement of unimplemented method */ MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value); /** @@ -716,7 +717,6 @@ MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value); * @return [mrb_value] The newly duplicated object. */ MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj); -MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method); /** * Returns true if obj responds to the given method. If the method was defined for that @@ -783,7 +783,7 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o #define MRB_ARGS_REQ(n) ((mrb_aspec)((n)&0x1f) << 18) /** - * Funtion takes n optional arguments + * Function takes n optional arguments * * @param n * The number of optional arguments. @@ -791,7 +791,7 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o #define MRB_ARGS_OPT(n) ((mrb_aspec)((n)&0x1f) << 13) /** - * Funtion takes n1 mandatory arguments and n2 optional arguments + * Function takes n1 mandatory arguments and n2 optional arguments * * @param n1 * The number of required arguments. @@ -836,15 +836,17 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o * | `S` | {String} | {mrb_value} | when `!` follows, the value may be `nil` | * | `A` | {Array} | {mrb_value} | when `!` follows, the value may be `nil` | * | `H` | {Hash} | {mrb_value} | when `!` follows, the value may be `nil` | - * | `s` | {String} | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` | + * | `s` | {String} | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` | * | `z` | {String} | 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` | {Float} | {mrb_float} | | - * | `i` | {Integer} | {mrb_int} | | + * | `f` | {Fixnum}/{Float} | {mrb_float} | | + * | `i` | {Fixnum}/{Float} | {mrb_int} | | * | `b` | boolean | {mrb_bool} | | - * | `n` | {Symbol} | {mrb_sym} | | + * | `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` | + * | `I` | inline struct | void * | | * | `&` | block | {mrb_value} | &! raises exception if no block given. | - * | `*` | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array; *! avoid copy of the stack. | + * | `*` | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array; `*!` avoid copy of the stack. | * | | | optional | | After this spec following specs would be optional. | * | `?` | optional given | {mrb_bool} | `TRUE` if preceding argument is given. Used to check optional argument is given. | * @@ -855,10 +857,6 @@ typedef const char *mrb_args_format; /** * Retrieve arguments from mrb_state. * - * When applicable, implicit conversions (such as `to_str`, `to_ary`, `to_hash`) are - * applied to received arguments. - * Used inside a function of mrb_func_t type. - * * @param mrb The current MRuby state. * @param format [mrb_args_format] is a list of format specifiers * @param ... The passing variadic arguments must be a pointer of retrieving type. @@ -867,7 +865,7 @@ typedef const char *mrb_args_format; */ MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...); -static inline mrb_sym +MRB_INLINE mrb_sym mrb_get_mid(mrb_state *mrb) /* get method symbol */ { return mrb->c->ci->mid; @@ -994,13 +992,13 @@ MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len); #define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit)) #ifdef _WIN32 -char* mrb_utf8_from_locale(const char *p, int len); -char* mrb_locale_from_utf8(const char *p, int len); +MRB_API char* mrb_utf8_from_locale(const char *p, int len); +MRB_API char* mrb_locale_from_utf8(const char *p, int len); #define mrb_locale_free(p) free(p) #define mrb_utf8_free(p) free(p) #else -#define mrb_utf8_from_locale(p, l) ((char*)p) -#define mrb_locale_from_utf8(p, l) ((char*)p) +#define mrb_utf8_from_locale(p, l) ((char*)(p)) +#define mrb_locale_from_utf8(p, l) ((char*)(p)) #define mrb_locale_free(p) #define mrb_utf8_free(p) #endif @@ -1080,16 +1078,13 @@ MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val); MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); -static inline int mrb_gc_arena_save(mrb_state*); -static inline void mrb_gc_arena_restore(mrb_state*,int); - -static inline int +MRB_INLINE int mrb_gc_arena_save(mrb_state *mrb) { return mrb->gc.arena_idx; } -static inline void +MRB_INLINE void mrb_gc_arena_restore(mrb_state *mrb, int idx) { mrb->gc.arena_idx = idx; @@ -1140,10 +1135,13 @@ MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc); MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg); MRB_API mrb_noreturn void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...); MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...); +MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj); MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...); MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...); MRB_API void mrb_print_backtrace(mrb_state *mrb); MRB_API void mrb_print_error(mrb_state *mrb); +/* function for `raisef` formatting */ +MRB_API mrb_value mrb_vformat(mrb_state *mrb, const char *format, va_list ap); /* macros to get typical exception objects note: @@ -1188,8 +1186,14 @@ 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)) +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); +MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o) +{ + if (MRB_FROZEN_P((struct RBasic*)o)) mrb_frozen_error(mrb, o); +} + typedef enum call_type { CALL_PUBLIC, CALL_FCALL, @@ -1197,7 +1201,7 @@ typedef enum call_type { CALL_TYPE_MAX } call_type; -MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2); +MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *c, const char *a, const char *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); @@ -1235,6 +1239,7 @@ MRB_API mrb_value mrb_fiber_alive_p(mrb_state *mrb, mrb_value fib); * @mrbgem mruby-fiber */ #define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError")) +MRB_API void mrb_stack_extend(mrb_state*, mrb_int); /* memory pool implementation */ typedef struct mrb_pool mrb_pool; @@ -1243,6 +1248,7 @@ MRB_API void mrb_pool_close(struct mrb_pool*); MRB_API void* mrb_pool_alloc(struct mrb_pool*, size_t); MRB_API void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen); MRB_API mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t); +/* temporary memory allocation, only effective while GC arena is kept */ MRB_API void* mrb_alloca(mrb_state *mrb, size_t); MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func); diff --git a/include/mruby/array.h b/include/mruby/array.h index 6fffe4512..0c0a002f5 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -33,7 +33,6 @@ struct RArray { } aux; mrb_value *ptr; } heap; - mrb_value embed[MRB_ARY_EMBED_LEN_MAX]; } as; }; @@ -46,7 +45,7 @@ struct RArray { #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) (&((a)->as.embed[0])) +#define ARY_EMBED_PTR(a) ((mrb_value*)&(a)->as) #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) @@ -199,6 +198,7 @@ MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val * @param other The array to replace it with. */ MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other); +MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self); MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self); /* @@ -227,6 +227,22 @@ MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset); /* + * Replace subsequence of an array. + * + * Equivalent to: + * + * ary.shift + * + * @param mrb The mruby state reference. + * @param self The array from which the value will be shifted. + * @param head Beginning position of a replacement subsequence. + * @param len Length of a replacement subsequence. + * @param rpl The array of replacement elements. + * @return The receiver array. + */ +MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value self, mrb_int head, mrb_int len, mrb_value rpl); + +/* * Shifts the first element from the array. * * Equivalent to: diff --git a/include/mruby/boxing_nan.h b/include/mruby/boxing_nan.h index 3d9bbdc69..ff6f6082d 100644 --- a/include/mruby/boxing_nan.h +++ b/include/mruby/boxing_nan.h @@ -81,7 +81,7 @@ typedef struct mrb_value { } while (0) #define SET_FLOAT_VALUE(mrb,r,v) do { \ - if (v != v) { \ + if ((v) != (v)) { \ (r).value.ttt = 0x7ff80000; \ (r).value.i = 0; \ } \ diff --git a/include/mruby/boxing_word.h b/include/mruby/boxing_word.h index b17bfc973..f16968a1f 100644 --- a/include/mruby/boxing_word.h +++ b/include/mruby/boxing_word.h @@ -45,6 +45,14 @@ enum mrb_special_consts { #define MRB_SYMBOL_FLAG 0x0e #define MRB_SPECIAL_SHIFT 8 +#if defined(MRB_64BIT) +#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT) +#define MRB_SYMBOL_MAX UINT32_MAX +#else +#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT - MRB_SPECIAL_SHIFT) +#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SPECIAL_SHIFT) +#endif + typedef union mrb_value { union { void *p; @@ -54,7 +62,7 @@ typedef union mrb_value { }; struct { unsigned int sym_flag : MRB_SPECIAL_SHIFT; - mrb_sym sym : (sizeof(mrb_sym) * CHAR_BIT); + mrb_sym sym : MRB_SYMBOL_BITSIZE; }; struct RBasic *bp; #ifndef MRB_WITHOUT_FLOAT @@ -83,7 +91,7 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); #define mrb_fixnum(o) ((mrb_int)(o).value.i) #define mrb_symbol(o) (o).value.sym -static inline enum mrb_vtype +MRB_INLINE enum mrb_vtype mrb_type(mrb_value o) { switch (o.w) { @@ -108,29 +116,31 @@ mrb_type(mrb_value o) #define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG) #define mrb_undef_p(o) ((o).w == MRB_Qundef) #define mrb_nil_p(o) ((o).w == MRB_Qnil) - -#define BOXWORD_SET_VALUE(o, ttt, attr, v) do { \ - switch (ttt) {\ - case MRB_TT_FALSE: (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\ - case MRB_TT_TRUE: (o).w = MRB_Qtrue; break;\ - case MRB_TT_UNDEF: (o).w = MRB_Qundef; break;\ - case MRB_TT_FIXNUM: (o).w = 0;(o).value.i_flag = MRB_FIXNUM_FLAG; (o).attr = (v); break;\ - case MRB_TT_SYMBOL: (o).w = 0;(o).value.sym_flag = MRB_SYMBOL_FLAG; (o).attr = (v); break;\ - default: (o).w = 0; (o).attr = (v); if ((o).value.bp) (o).value.bp->tt = ttt; break;\ - }\ -} while (0) +#define mrb_false_p(o) ((o).w == MRB_Qfalse) +#define mrb_true_p(o) ((o).w == MRB_Qtrue) #ifndef MRB_WITHOUT_FLOAT -#define SET_FLOAT_VALUE(mrb,r,v) r = mrb_word_boxing_float_value(mrb, v) +#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_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0) -#define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1) -#define SET_TRUE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_TRUE, value.i, 1) -#define SET_BOOL_VALUE(r,b) BOXWORD_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1) -#define SET_INT_VALUE(r,n) BOXWORD_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n)) -#define SET_SYM_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) -#define SET_OBJ_VALUE(r,v) BOXWORD_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v)) -#define SET_UNDEF_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0) +#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_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r)) +#define SET_INT_VALUE(r,n) do { \ + (r).w = 0; \ + (r).value.i_flag = MRB_FIXNUM_FLAG; \ + (r).value.i = (n); \ +} while (0) +#define SET_SYM_VALUE(r,v) do { \ + (r).w = 0; \ + (r).value.sym_flag = MRB_SYMBOL_FLAG; \ + (r).value.sym = (v); \ +} while (0) +#define SET_OBJ_VALUE(r,v) do { \ + (r).w = 0; \ + (r).value.p = (v); \ +} while (0) #endif /* MRUBY_BOXING_WORD_H */ diff --git a/include/mruby/class.h b/include/mruby/class.h index ea35d8e17..c79a487b5 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -22,11 +22,8 @@ struct RClass { }; #define mrb_class_ptr(v) ((struct RClass*)(mrb_ptr(v))) -#define RCLASS_SUPER(v) (((struct RClass*)(mrb_ptr(v)))->super) -#define RCLASS_IV_TBL(v) (((struct RClass*)(mrb_ptr(v)))->iv) -#define RCLASS_M_TBL(v) (((struct RClass*)(mrb_ptr(v)))->mt) -static inline struct RClass* +MRB_INLINE struct RClass* mrb_class(mrb_state *mrb, mrb_value v) { switch (mrb_type(v)) { @@ -53,22 +50,28 @@ mrb_class(mrb_state *mrb, mrb_value v) } } -/* TODO: figure out where to put user flags */ -/* flags bits >= 18 is reserved */ -#define MRB_FLAG_IS_PREPENDED (1 << 19) -#define MRB_FLAG_IS_ORIGIN (1 << 20) +/* flags: + 20: frozen + 19: is_prepended + 18: is_origin + 17: is_inherited (used by method cache) + 16: unused + 0-15: instance type +*/ +#define MRB_FL_CLASS_IS_PREPENDED (1 << 19) +#define MRB_FL_CLASS_IS_ORIGIN (1 << 18) #define MRB_CLASS_ORIGIN(c) do {\ - if (c->flags & MRB_FLAG_IS_PREPENDED) {\ - c = c->super;\ - while (!(c->flags & MRB_FLAG_IS_ORIGIN)) {\ - c = c->super;\ + if ((c)->flags & MRB_FL_CLASS_IS_PREPENDED) {\ + (c) = (c)->super;\ + while (!((c)->flags & MRB_FL_CLASS_IS_ORIGIN)) {\ + (c) = (c)->super;\ }\ }\ } while (0) -#define MRB_FLAG_IS_INHERITED (1 << 21) +#define MRB_FL_CLASS_IS_INHERITED (1 << 17) #define MRB_INSTANCE_TT_MASK (0xFF) -#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) +#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); @@ -76,14 +79,16 @@ MRB_API struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb MRB_API 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 *mrb, struct RClass *c, mrb_sym a, mrb_sym b); +MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b); 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); MRB_API struct RClass* mrb_class_real(struct RClass* cl); +mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym); +mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int); mrb_value mrb_class_find_path(mrb_state*, struct RClass*); void mrb_gc_mark_mt(mrb_state*, struct RClass*); size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); diff --git a/include/mruby/common.h b/include/mruby/common.h index d6ec78b0d..dc9e3acc5 100644 --- a/include/mruby/common.h +++ b/include/mruby/common.h @@ -7,6 +7,11 @@ #ifndef MRUBY_COMMON_H #define MRUBY_COMMON_H +#ifdef __APPLE__ + #ifndef __TARGETCONDITIONALS__ + #include "TargetConditionals.h" + #endif +#endif #ifdef __cplusplus #ifdef MRB_ENABLE_CXX_ABI @@ -29,7 +34,7 @@ MRB_BEGIN_DECL /** Declare a function that never returns. */ -#if __STDC_VERSION__ >= 201112L +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L # define mrb_noreturn _Noreturn #elif defined __GNUC__ && !defined __STRICT_ANSI__ # define mrb_noreturn __attribute__((noreturn)) @@ -49,12 +54,12 @@ MRB_BEGIN_DECL #endif /** Declare a function as always inlined. */ -#if defined(_MSC_VER) -# define MRB_INLINE static __inline -#else -# define MRB_INLINE static inline +#if defined _MSC_VER && _MSC_VER < 1900 +# ifndef __cplusplus +# define inline __inline +# endif #endif - +#define MRB_INLINE static inline /** Declare a public MRuby API function. */ #if defined(MRB_BUILD_AS_DLL) diff --git a/include/mruby/compile.h b/include/mruby/compile.h index d7d029616..3b25ff526 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -24,7 +24,7 @@ typedef struct mrbc_context { mrb_sym *syms; int slen; char *filename; - short lineno; + uint16_t lineno; int (*partial_hook)(struct mrb_parser_state*); void *partial_data; struct RClass *target_class; @@ -33,6 +33,7 @@ typedef struct mrbc_context { mrb_bool no_exec:1; mrb_bool keep_lv:1; mrb_bool no_optimize:1; + mrb_bool on_eval:1; size_t parser_nerr; } mrbc_context; @@ -66,7 +67,7 @@ enum mrb_lex_state_enum { /* saved error message */ struct mrb_parser_message { - int lineno; + uint16_t lineno; int column; char* message; }; @@ -104,7 +105,7 @@ struct mrb_parser_heredoc_info { mrb_ast_node *doc; }; -#define MRB_PARSER_TOKBUF_MAX 65536 +#define MRB_PARSER_TOKBUF_MAX (UINT16_MAX-1) #define MRB_PARSER_TOKBUF_SIZE 256 /* parser structure */ @@ -117,8 +118,8 @@ struct mrb_parser_state { FILE *f; #endif mrbc_context *cxt; - char const *filename; - int lineno; + mrb_sym filename_sym; + uint16_t lineno; int column; enum mrb_lex_state_enum lstate; @@ -142,7 +143,6 @@ struct mrb_parser_state { mrb_ast_node *heredocs_from_nextline; mrb_ast_node *parsing_heredoc; mrb_ast_node *lex_strterm_before_heredoc; - mrb_bool heredoc_end_now:1; /* for mirb */ void *ylval; @@ -151,13 +151,14 @@ struct mrb_parser_state { mrb_ast_node *tree; mrb_bool no_optimize:1; + mrb_bool on_eval:1; mrb_bool capture_errors:1; struct mrb_parser_message error_buffer[10]; struct mrb_parser_message warn_buffer[10]; mrb_sym* filename_table; - size_t filename_table_length; - int current_filename_index; + uint16_t filename_table_length; + uint16_t current_filename_index; struct mrb_jmpbuf* jmp; }; @@ -167,7 +168,7 @@ MRB_API void mrb_parser_free(struct mrb_parser_state*); MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*); MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*); -MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx); +MRB_API mrb_sym mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx); /* utility functions */ #ifndef MRB_DISABLE_STDIO diff --git a/include/mruby/data.h b/include/mruby/data.h index 590470528..54466dcd6 100644 --- a/include/mruby/data.h +++ b/include/mruby/data.h @@ -39,10 +39,11 @@ MRB_API struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass #define Data_Wrap_Struct(mrb,klass,type,ptr)\ mrb_data_object_alloc(mrb,klass,ptr,type) -#define Data_Make_Struct(mrb,klass,strct,type,sval,data) do { \ - sval = mrb_malloc(mrb, sizeof(strct)); \ - { static const strct zero = { 0 }; *sval = zero; };\ - data = Data_Wrap_Struct(mrb,klass,type,sval);\ +#define Data_Make_Struct(mrb,klass,strct,type,sval,data_obj) do { \ + (data_obj) = Data_Wrap_Struct(mrb,klass,type,NULL);\ + (sval) = (strct *)mrb_malloc(mrb, sizeof(strct)); \ + { static const strct zero = { 0 }; *(sval) = zero; };\ + (data_obj)->data = (sval);\ } while (0) #define RDATA(obj) ((struct RData *)(mrb_ptr(obj))) @@ -62,7 +63,7 @@ MRB_API void *mrb_data_check_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_t *(void**)&sval = mrb_data_get_ptr(mrb, obj, type); \ } while (0) -static inline void +MRB_INLINE void mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type) { mrb_assert(mrb_type(v) == MRB_TT_DATA); diff --git a/include/mruby/debug.h b/include/mruby/debug.h index d1de34882..e08c47cfc 100644 --- a/include/mruby/debug.h +++ b/include/mruby/debug.h @@ -26,7 +26,6 @@ typedef struct mrb_irep_debug_info_line { typedef struct mrb_irep_debug_info_file { uint32_t start_pos; - const char *filename; mrb_sym filename_sym; uint32_t line_entry_count; mrb_debug_line_type line_type; @@ -47,18 +46,19 @@ 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_irep *irep, ptrdiff_t pc); +MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc); /* * get line from irep's debug info and program counter * @return returns -1 if not found */ -MRB_API int32_t mrb_debug_get_line(mrb_irep *irep, ptrdiff_t pc); +MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc); +MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep); MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file( - mrb_state *mrb, mrb_irep *irep, + mrb_state *mrb, mrb_irep_debug_info *info, + const char *filename, uint16_t *lines, uint32_t start_pos, uint32_t end_pos); -MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep); MRB_API void mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d); MRB_END_DECL diff --git a/include/mruby/dump.h b/include/mruby/dump.h index f56d66a32..65ed8af9d 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -31,6 +31,7 @@ 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*); #endif MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*); +MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t); /* dump/load error code * @@ -52,15 +53,14 @@ MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*); /* Rite Binary File header */ #define RITE_BINARY_IDENT "RITE" #define RITE_BINARY_IDENT_LIL "ETIR" -#define RITE_BINARY_FORMAT_VER "0004" +#define RITE_BINARY_FORMAT_VER "0006" #define RITE_COMPILER_NAME "MATZ" #define RITE_COMPILER_VERSION "0000" -#define RITE_VM_VER "0000" +#define RITE_VM_VER "0002" #define RITE_BINARY_EOF "END\0" #define RITE_SECTION_IREP_IDENT "IREP" -#define RITE_SECTION_LINENO_IDENT "LINE" #define RITE_SECTION_DEBUG_IDENT "DBG\0" #define RITE_SECTION_LV_IDENT "LVAR" @@ -92,10 +92,6 @@ struct rite_section_irep_header { uint8_t rite_version[4]; /* Rite Instruction Specification Version */ }; -struct rite_section_lineno_header { - RITE_SECTION_HEADER; -}; - struct rite_section_debug_header { RITE_SECTION_HEADER; }; diff --git a/include/mruby/error.h b/include/mruby/error.h index 1587795fc..237c701ad 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -29,7 +29,7 @@ MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb); MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...); -/* declaration for fail method */ +/* declaration for `fail` method */ MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); struct RBreak { diff --git a/include/mruby/hash.h b/include/mruby/hash.h index 1a870785a..7e2ed5596 100644 --- a/include/mruby/hash.h +++ b/include/mruby/hash.h @@ -8,7 +8,6 @@ #define MRUBY_HASH_H #include "common.h" -#include <mruby/khash.h> /** * Hash class @@ -18,13 +17,15 @@ MRB_BEGIN_DECL struct RHash { MRB_OBJECT_HEADER; struct iv_tbl *iv; - struct kh_ht *ht; + struct htable *ht; }; #define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v))) #define mrb_hash_value(p) mrb_obj_value((void*)(p)) MRB_API mrb_value mrb_hash_new_capa(mrb_state*, mrb_int); +MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash); +MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); /* * Initializes a new hash. @@ -74,7 +75,7 @@ MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key); * * Equivalent to: * - * hash.hash_key?(key) ? hash[key] : def + * hash.key?(key) ? hash[key] : def * * @param mrb The mruby state reference. * @param hash The target hash. @@ -110,7 +111,19 @@ MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value * @return An array with the keys of the hash. */ MRB_API mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash); -MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); +/* + * Check if the hash has the key. + * + * Equivalent to: + * + * hash.key?(key) + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @param key The key to check existence. + * @return True if the hash has the key + */ +MRB_API mrb_bool mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key); /* * Check if the hash is empty @@ -123,7 +136,7 @@ MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); * @param self The target hash. * @return True if the hash is empty, false otherwise. */ -MRB_API mrb_value mrb_hash_empty_p(mrb_state *mrb, mrb_value self); +MRB_API mrb_bool mrb_hash_empty_p(mrb_state *mrb, mrb_value self); /* * Gets an array of values. @@ -151,21 +164,51 @@ MRB_API mrb_value mrb_hash_values(mrb_state *mrb, mrb_value hash); */ MRB_API mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash); -/* declaration of struct kh_ht */ +/* + * Get hash size. + * + * Equivalent to: + * + * hash.size + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @return The hash size. + */ +MRB_API mrb_int mrb_hash_size(mrb_state *mrb, mrb_value hash); + +/* + * Copies the hash. + * + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @return The copy of the hash + */ +MRB_API mrb_value mrb_hash_dup(mrb_state *mrb, mrb_value hash); + +/* + * Merges two hashes. The first hash will be modified by the + * second hash. + * + * @param mrb The mruby state reference. + * @param hash1 The target hash. + * @param hash2 Updating hash + */ +MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2); + +/* declaration of struct mrb_hash_value */ /* be careful when you touch the internal */ typedef struct { mrb_value v; mrb_int n; } mrb_hash_value; -KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE) - /* 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_PROCDEFAULT(h) RHASH_IFNONE(h) -MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash); #define MRB_HASH_DEFAULT 1 #define MRB_HASH_PROC_DEFAULT 2 @@ -177,6 +220,10 @@ void mrb_gc_mark_hash(mrb_state*, struct RHash*); size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); void mrb_gc_free_hash(mrb_state*, struct RHash*); +/* return non zero to break the loop */ +typedef int (mrb_hash_foreach_func)(mrb_state *mrb, mrb_value key, mrb_value val, void *data); +MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p); + MRB_END_DECL #endif /* MRUBY_HASH_H */ diff --git a/include/mruby/irep.h b/include/mruby/irep.h index efd226793..d42fd0fb8 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -39,23 +39,48 @@ typedef struct mrb_irep { struct mrb_locals *lv; /* debug info */ - mrb_bool own_filename; - const char *filename; - uint16_t *lines; struct mrb_irep_debug_info* debug_info; - int ilen, plen, slen, rlen, refcnt; + uint16_t ilen, plen, slen, rlen; + uint32_t refcnt; } mrb_irep; #define MRB_ISEQ_NO_FREE 1 MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb); + +/* @param [const uint8_t*] irep code, expected as a literal */ MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*); + +/* + * @param [const void*] irep code + * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted. + */ +MRB_API mrb_value mrb_load_irep_buf(mrb_state*, const void*, size_t); + +/* @param [const uint8_t*] irep code, expected as a literal */ MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*); + +/* + * @param [const void*] irep code + * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted. + */ +MRB_API mrb_value mrb_load_irep_buf_cxt(mrb_state*, const void*, size_t, mrbc_context*); + void mrb_irep_free(mrb_state*, struct mrb_irep*); void mrb_irep_incref(mrb_state*, struct mrb_irep*); void mrb_irep_decref(mrb_state*, struct mrb_irep*); void mrb_irep_cutref(mrb_state*, struct mrb_irep*); +void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep); + +struct mrb_insn_data { + uint8_t insn; + uint16_t a; + uint16_t b; + uint8_t c; +}; + +struct mrb_insn_data mrb_decode_insn(mrb_code *pc); MRB_END_DECL diff --git a/include/mruby/istruct.h b/include/mruby/istruct.h index 4d2393ccd..23c9bfa36 100644 --- a/include/mruby/istruct.h +++ b/include/mruby/istruct.h @@ -19,12 +19,12 @@ MRB_BEGIN_DECL #define ISTRUCT_DATA_SIZE (sizeof(void*) * 3) -struct RIstruct { +struct RIStruct { MRB_OBJECT_HEADER; char inline_data[ISTRUCT_DATA_SIZE]; }; -#define RISTRUCT(obj) ((struct RIstruct*)(mrb_ptr(obj))) +#define RISTRUCT(obj) ((struct RIStruct*)(mrb_ptr(obj))) #define ISTRUCT_PTR(obj) (RISTRUCT(obj)->inline_data) MRB_INLINE mrb_int mrb_istruct_size() diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index da9225aaa..34707e441 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -23,7 +23,7 @@ MRB_BEGIN_DECL #define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int) #define FIXABLE(f) TYPED_FIXABLE(f,mrb_int) #ifndef MRB_WITHOUT_FLOAT -#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,double) +#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,mrb_float) #endif #ifndef MRB_WITHOUT_FLOAT @@ -34,12 +34,12 @@ MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base); #ifndef MRB_WITHOUT_FLOAT MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); 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_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y); -mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y); -mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y); -mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y); +MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y); +MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y); +MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y); #ifndef __has_builtin #define __has_builtin(x) 0 diff --git a/include/mruby/object.h b/include/mruby/object.h index 4f2134ae2..373e3bec7 100644 --- a/include/mruby/object.h +++ b/include/mruby/object.h @@ -14,7 +14,7 @@ struct RClass *c;\ struct RBasic *gcnext -#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag) +#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & (flag)) struct RBasic { @@ -22,11 +22,10 @@ struct RBasic { }; #define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v))) -/* flags bits >= 18 is reserved */ -#define MRB_FLAG_IS_FROZEN (1 << 18) -#define MRB_FROZEN_P(o) ((o)->flags & MRB_FLAG_IS_FROZEN) -#define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FLAG_IS_FROZEN) -#define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FLAG_IS_FROZEN) +#define MRB_FL_OBJ_IS_FROZEN (1 << 20) +#define MRB_FROZEN_P(o) ((o)->flags & MRB_FL_OBJ_IS_FROZEN) +#define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FL_OBJ_IS_FROZEN) +#define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FL_OBJ_IS_FROZEN) struct RObject { MRB_OBJECT_HEADER; diff --git a/include/mruby/opcode.h b/include/mruby/opcode.h index a5e3af158..d513ca472 100644 --- a/include/mruby/opcode.h +++ b/include/mruby/opcode.h @@ -7,145 +7,10 @@ #ifndef MRUBY_OPCODE_H #define MRUBY_OPCODE_H -#define MAXARG_Bx (0xffff) -#define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */ - -/* instructions: packed 32 bit */ -/* ------------------------------- */ -/* A:B:C:OP = 9: 9: 7: 7 */ -/* A:Bx:OP = 9:16: 7 */ -/* Ax:OP = 25: 7 */ -/* A:Bz:Cz:OP = 9:14: 2: 7 */ - -#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f)) -#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff)) -#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff)) -#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f)) -#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff)) -#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx)) -#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff)) -#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1)))) -#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1)))) -#define GETARG_b(i) GETARG_UNPACK_b(i,14,2) -#define GETARG_c(i) GETARG_UNPACK_c(i,14,2) - -#define MKOPCODE(op) ((op) & 0x7f) -#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23) -#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14) -#define MKARG_C(c) (((c) & 0x7f) << 7) -#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7) -#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx) -#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7) -#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7)) -#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2) - -#define MKOP_A(op,a) (MKOPCODE(op)|MKARG_A(a)) -#define MKOP_AB(op,a,b) (MKOP_A(op,a)|MKARG_B(b)) -#define MKOP_ABC(op,a,b,c) (MKOP_AB(op,a,b)|MKARG_C(c)) -#define MKOP_ABx(op,a,bx) (MKOP_A(op,a)|MKARG_Bx(bx)) -#define MKOP_Bx(op,bx) (MKOPCODE(op)|MKARG_Bx(bx)) -#define MKOP_sBx(op,sbx) (MKOPCODE(op)|MKARG_sBx(sbx)) -#define MKOP_AsBx(op,a,sbx) (MKOP_A(op,a)|MKARG_sBx(sbx)) -#define MKOP_Ax(op,ax) (MKOPCODE(op)|MKARG_Ax(ax)) -#define MKOP_Abc(op,a,b,c) (MKOP_A(op,a)|MKARG_bc(b,c)) - -enum { - /*----------------------------------------------------------------------- - operation code operand description - ------------------------------------------------------------------------*/ - OP_NOP=0,/* */ - OP_MOVE,/* A B R(A) := R(B) */ - OP_LOADL,/* A Bx R(A) := Pool(Bx) */ - OP_LOADI,/* A sBx R(A) := sBx */ - OP_LOADSYM,/* A Bx R(A) := Syms(Bx) */ - OP_LOADNIL,/* A R(A) := nil */ - OP_LOADSELF,/* A R(A) := self */ - OP_LOADT,/* A R(A) := true */ - OP_LOADF,/* A R(A) := false */ - - OP_GETGLOBAL,/* A Bx R(A) := getglobal(Syms(Bx)) */ - OP_SETGLOBAL,/* A Bx setglobal(Syms(Bx), R(A)) */ - OP_GETSPECIAL,/*A Bx R(A) := Special[Bx] */ - OP_SETSPECIAL,/*A Bx Special[Bx] := R(A) */ - OP_GETIV,/* A Bx R(A) := ivget(Syms(Bx)) */ - OP_SETIV,/* A Bx ivset(Syms(Bx),R(A)) */ - OP_GETCV,/* A Bx R(A) := cvget(Syms(Bx)) */ - OP_SETCV,/* A Bx cvset(Syms(Bx),R(A)) */ - OP_GETCONST,/* A Bx R(A) := constget(Syms(Bx)) */ - OP_SETCONST,/* A Bx constset(Syms(Bx),R(A)) */ - OP_GETMCNST,/* A Bx R(A) := R(A)::Syms(Bx) */ - OP_SETMCNST,/* A Bx R(A+1)::Syms(Bx) := R(A) */ - OP_GETUPVAR,/* A B C R(A) := uvget(B,C) */ - OP_SETUPVAR,/* A B C uvset(B,C,R(A)) */ - - OP_JMP,/* sBx pc+=sBx */ - OP_JMPIF,/* A sBx if R(A) pc+=sBx */ - OP_JMPNOT,/* A sBx if !R(A) pc+=sBx */ - OP_ONERR,/* sBx rescue_push(pc+sBx) */ - OP_RESCUE,/* A B C if A (if C exc=R(A) else R(A) := exc); - if B R(B) := exc.isa?(R(B)); clear(exc) */ - OP_POPERR,/* A A.times{rescue_pop()} */ - OP_RAISE,/* A raise(R(A)) */ - OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */ - OP_EPOP,/* A A.times{ensure_pop().call} */ - - OP_SEND,/* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */ - OP_SENDB,/* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/ - OP_FSEND,/* A B C R(A) := fcall(R(A),Syms(B),R(A+1),...,R(A+C-1)) */ - OP_CALL,/* A R(A) := self.call(frame.argc, frame.argv) */ - OP_SUPER,/* A C R(A) := super(R(A+1),... ,R(A+C+1)) */ - OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */ - OP_ENTER,/* Ax arg setup according to flags (23=5:5:1:5:5:1:1) */ - OP_KARG,/* A B C R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */ - OP_KDICT,/* A C R(A) := kdict */ - - OP_RETURN,/* A B return R(A) (B=normal,in-block return/break) */ - OP_TAILCALL,/* A B C return call(R(A),Syms(B),*R(C)) */ - OP_BLKPUSH,/* A Bx R(A) := block (16=6:1:5:4) */ - - OP_ADD,/* A B C R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1) */ - OP_ADDI,/* A B C R(A) := R(A)+C (Syms[B]=:+) */ - OP_SUB,/* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1) */ - OP_SUBI,/* A B C R(A) := R(A)-C (Syms[B]=:-) */ - OP_MUL,/* A B C R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1) */ - OP_DIV,/* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1) */ - OP_EQ,/* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1) */ - OP_LT,/* A B C R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1) */ - OP_LE,/* A B C R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1) */ - OP_GT,/* A B C R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1) */ - OP_GE,/* A B C R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1) */ - - OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ - OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */ - OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */ - OP_AREF,/* A B C R(A) := R(B)[C] */ - OP_ASET,/* A B C R(B)[C] := R(A) */ - OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A)[B..] */ - - OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */ - OP_STRCAT,/* A B str_cat(R(A),R(B)) */ - - OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */ - OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cz) */ - OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */ - - OP_OCLASS,/* A R(A) := ::Object */ - OP_CLASS,/* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */ - OP_MODULE,/* A B R(A) := newmodule(R(A),Syms(B)) */ - OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */ - OP_METHOD,/* A B R(A).newmethod(Syms(B),R(A+1)) */ - OP_SCLASS,/* A B R(A) := R(B).singleton_class */ - OP_TCLASS,/* A R(A) := target_class */ - - OP_DEBUG,/* A B C print R(A),R(B),R(C) */ - OP_STOP,/* stop VM */ - OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */ - - OP_RSVD1,/* reserved instruction #1 */ - OP_RSVD2,/* reserved instruction #2 */ - OP_RSVD3,/* reserved instruction #3 */ - OP_RSVD4,/* reserved instruction #4 */ - OP_RSVD5,/* reserved instruction #5 */ +enum mrb_insn { +#define OPCODE(x,_) OP_ ## x, +#include "mruby/ops.h" +#undef OPCODE }; #define OP_L_STRICT 1 @@ -158,4 +23,47 @@ enum { #define OP_R_BREAK 1 #define OP_R_RETURN 2 +#define PEEK_B(pc) (*(pc)) +#define PEEK_S(pc) ((pc)[0]<<8|(pc)[1]) +#define PEEK_W(pc) ((pc)[0]<<16|(pc)[1]<<8|(pc)[2]) + +#define READ_B() PEEK_B(pc++) +#define READ_S() (pc+=2, PEEK_S(pc-2)) +#define READ_W() (pc+=3, PEEK_W(pc-3)) + +#define FETCH_Z() /* nothing */ +#define FETCH_B() do {a=READ_B();} while (0) +#define FETCH_BB() do {a=READ_B(); b=READ_B();} while (0) +#define FETCH_BBB() do {a=READ_B(); b=READ_B(); c=READ_B();} while (0) +#define FETCH_BS() do {a=READ_B(); b=READ_S();} while (0) +#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 new file mode 100644 index 000000000..d64594625 --- /dev/null +++ b/include/mruby/ops.h @@ -0,0 +1,117 @@ +/* operand types: + + Z: no operand (Z,Z,Z,Z) + + B: 8bit (B,S,B,B) + + BB: 8+8bit (BB,SB,BS,SS) + + BBB: 8+8+8bit (BBB,SBB,BSB,SSB) + + BS: 8+16bit (BS,SS,BS,BS) + + S: 16bit (S,S,S,S) + + W: 24bit (W,W,W,W) +*/ + +/*----------------------------------------------------------------------- +operation code operands semantics +------------------------------------------------------------------------*/ +OPCODE(NOP, Z) /* no operation */ +OPCODE(MOVE, BB) /* R(a) = R(b) */ +OPCODE(LOADL, BB) /* R(a) = Pool(b) */ +OPCODE(LOADI, BB) /* R(a) = mrb_int(b) */ +OPCODE(LOADINEG, BB) /* R(a) = mrb_int(-b) */ +OPCODE(LOADI__1, B) /* R(a) = mrb_int(-1) */ +OPCODE(LOADI_0, B) /* R(a) = mrb_int(0) */ +OPCODE(LOADI_1, B) /* R(a) = mrb_int(1) */ +OPCODE(LOADI_2, B) /* R(a) = mrb_int(2) */ +OPCODE(LOADI_3, B) /* R(a) = mrb_int(3) */ +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(LOADSYM, BB) /* R(a) = Syms(b) */ +OPCODE(LOADNIL, B) /* R(a) = nil */ +OPCODE(LOADSELF, B) /* R(a) = self */ +OPCODE(LOADT, B) /* R(a) = true */ +OPCODE(LOADF, B) /* R(a) = false */ +OPCODE(GETGV, BB) /* R(a) = getglobal(Syms(b)) */ +OPCODE(SETGV, BB) /* setglobal(Syms(b), R(a)) */ +OPCODE(GETSV, BB) /* R(a) = Special[Syms(b)] */ +OPCODE(SETSV, BB) /* Special[Syms(b)] = R(a) */ +OPCODE(GETIV, BB) /* R(a) = ivget(Syms(b)) */ +OPCODE(SETIV, BB) /* ivset(Syms(b),R(a)) */ +OPCODE(GETCV, BB) /* R(a) = cvget(Syms(b)) */ +OPCODE(SETCV, BB) /* cvset(Syms(b),R(a)) */ +OPCODE(GETCONST, BB) /* R(a) = constget(Syms(b)) */ +OPCODE(SETCONST, BB) /* constset(Syms(b),R(a)) */ +OPCODE(GETMCNST, BB) /* R(a) = R(a)::Syms(b) */ +OPCODE(SETMCNST, BB) /* R(a+1)::Syms(b) = R(a) */ +OPCODE(GETUPVAR, BBB) /* R(a) = uvget(b,c) */ +OPCODE(SETUPVAR, BBB) /* uvset(b,c,R(a)) */ +OPCODE(JMP, S) /* pc=a */ +OPCODE(JMPIF, BS) /* if R(b) pc=a */ +OPCODE(JMPNOT, BS) /* if !R(b) pc=a */ +OPCODE(JMPNIL, BS) /* if R(b)==nil pc=a */ +OPCODE(ONERR, S) /* rescue_push(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(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)) */ +OPCODE(SENDB, BBB) /* R(a) = call(R(a),Syms(Bx),R(a+1),...,R(a+c),&R(a+c+1)) */ +OPCODE(CALL, Z) /* R(0) = self.call(frame.argc, frame.argv) */ +OPCODE(SUPER, BB) /* R(a) = super(R(a+1),... ,R(a+b+1)) */ +OPCODE(ARGARY, BS) /* R(a) = argument array (16=m5:r1:m5:d1:lv4) */ +OPCODE(ENTER, W) /* arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1) */ +OPCODE(KEY_P, BB) /* R(a) = kdict.key?(Syms(b)) # todo */ +OPCODE(KEYEND, Z) /* raise unless kdict.empty? # todo */ +OPCODE(KARG, BB) /* R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) # todo */ +OPCODE(RETURN, B) /* return R(a) (normal) */ +OPCODE(RETURN_BLK, B) /* return R(a) (in-block return) */ +OPCODE(BREAK, B) /* break R(a) */ +OPCODE(BLKPUSH, BS) /* R(a) = block (16=m5:r1:m5:d1:lv4) */ +OPCODE(ADD, B) /* R(a) = R(a)+R(a+1) */ +OPCODE(ADDI, BB) /* R(a) = R(a)+mrb_int(c) */ +OPCODE(SUB, B) /* R(a) = R(a)-R(a+1) */ +OPCODE(SUBI, BB) /* R(a) = R(a)-C */ +OPCODE(MUL, B) /* R(a) = R(a)*R(a+1) */ +OPCODE(DIV, B) /* R(a) = R(a)/R(a+1) */ +OPCODE(EQ, B) /* R(a) = R(a)==R(a+1) */ +OPCODE(LT, B) /* R(a) = R(a)<R(a+1) */ +OPCODE(LE, B) /* R(a) = R(a)<=R(a+1) */ +OPCODE(GT, B) /* R(a) = R(a)>R(a+1) */ +OPCODE(GE, B) /* R(a) = R(a)>=R(a+1) */ +OPCODE(ARRAY, BB) /* R(a) = ary_new(R(a),R(a+1)..R(a+b)) */ +OPCODE(ARRAY2, BBB) /* R(a) = ary_new(R(b),R(b+1)..R(b+c)) */ +OPCODE(ARYCAT, B) /* ary_cat(R(a),R(a+1)) */ +OPCODE(ARYPUSH, B) /* ary_push(R(a),R(a+1)) */ +OPCODE(ARYDUP, B) /* R(a) = ary_dup(R(a)) */ +OPCODE(AREF, BBB) /* R(a) = R(b)[c] */ +OPCODE(ASET, BBB) /* R(a)[c] = R(b) */ +OPCODE(APOST, BBB) /* *R(a),R(a+1)..R(a+c) = R(a)[b..] */ +OPCODE(INTERN, B) /* R(a) = intern(R(a)) */ +OPCODE(STRING, BB) /* R(a) = str_dup(Lit(b)) */ +OPCODE(STRCAT, B) /* str_cat(R(a),R(a+1)) */ +OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b)) */ +OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b)) */ +OPCODE(HASHCAT, B) /* R(a) = hash_cat(R(a),R(a+1)) */ +OPCODE(LAMBDA, BB) /* R(a) = lambda(SEQ[b],L_LAMBDA) */ +OPCODE(BLOCK, BB) /* R(a) = lambda(SEQ[b],L_BLOCK) */ +OPCODE(METHOD, BB) /* R(a) = lambda(SEQ[b],L_METHOD) */ +OPCODE(RANGE_INC, B) /* R(a) = range_new(R(a),R(a+1),FALSE) */ +OPCODE(RANGE_EXC, B) /* R(a) = range_new(R(a),R(a+1),TRUE) */ +OPCODE(OCLASS, B) /* R(a) = ::Object */ +OPCODE(CLASS, BB) /* R(a) = newclass(R(a),Syms(b),R(a+1)) */ +OPCODE(MODULE, BB) /* R(a) = newmodule(R(a),Syms(b)) */ +OPCODE(EXEC, BB) /* R(a) = blockexec(R(a),SEQ[b]) */ +OPCODE(DEF, BB) /* R(a).newmethod(Syms(b),R(a+1)) */ +OPCODE(ALIAS, BB) /* alias_method(target_class,Syms(a),Syms(b)) */ +OPCODE(UNDEF, B) /* undef_method(target_class,Syms(a)) */ +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 */ diff --git a/include/mruby/proc.h b/include/mruby/proc.h index aa281b6dd..a8b16db1d 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -23,13 +23,13 @@ struct REnv { }; /* flags (21bits): 1(shared flag):10(cioff/bidx):10(stack_len) */ -#define MRB_ENV_SET_STACK_LEN(e,len) (e)->flags = (((e)->flags & ~0x3ff)|((unsigned int)(len) & 0x3ff)) +#define MRB_ENV_SET_STACK_LEN(e,len) ((e)->flags = (((e)->flags & ~0x3ff)|((unsigned int)(len) & 0x3ff))) #define MRB_ENV_STACK_LEN(e) ((mrb_int)((e)->flags & 0x3ff)) #define MRB_ENV_STACK_UNSHARED (1<<20) -#define MRB_ENV_UNSHARE_STACK(e) (e)->flags |= MRB_ENV_STACK_UNSHARED +#define MRB_ENV_UNSHARE_STACK(e) ((e)->flags |= MRB_ENV_STACK_UNSHARED) #define MRB_ENV_STACK_SHARED_P(e) (((e)->flags & MRB_ENV_STACK_UNSHARED) == 0) #define MRB_ENV_BIDX(e) (((e)->flags >> 10) & 0x3ff) -#define MRB_ENV_SET_BIDX(e,idx) (e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10) +#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10)) void mrb_env_unshare(mrb_state*, struct REnv*); @@ -69,11 +69,11 @@ struct RProc { #define MRB_PROC_SET_TARGET_CLASS(p,tc) do {\ if (MRB_PROC_ENV_P(p)) {\ (p)->e.env->c = (tc);\ - mrb_field_write_barrier(mrb, (struct RBasic*)(p)->e.env, (struct RBasic*)tc);\ + mrb_field_write_barrier(mrb, (struct RBasic*)(p)->e.env, (struct RBasic*)(tc));\ }\ else {\ (p)->e.target_class = (tc);\ - mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)tc);\ + mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)(tc));\ }\ } while (0) #define MRB_PROC_SCOPE 2048 @@ -86,9 +86,10 @@ struct RProc *mrb_closure_new(mrb_state*, 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_API mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); +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_func_t, mrb_int, const mrb_value*); @@ -101,8 +102,8 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int); #define MRB_METHOD_FUNC_FL ((uintptr_t)1) #define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL) #define MRB_METHOD_FUNC(m) ((mrb_func_t)((uintptr_t)(m)&(~MRB_METHOD_FUNC_FL))) -#define MRB_METHOD_FROM_FUNC(m,fn) m=(mrb_method_t)((struct RProc*)((uintptr_t)(fn)|MRB_METHOD_FUNC_FL)) -#define MRB_METHOD_FROM_PROC(m,pr) m=(mrb_method_t)(struct RProc*)(pr) +#define MRB_METHOD_FROM_FUNC(m,fn) ((m)=(mrb_method_t)((struct RProc*)((uintptr_t)(fn)|MRB_METHOD_FUNC_FL))) +#define MRB_METHOD_FROM_PROC(m,pr) ((m)=(mrb_method_t)(struct RProc*)(pr)) #define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m)) #define MRB_METHOD_PROC(m) ((struct RProc*)(m)) #define MRB_METHOD_UNDEF_P(m) ((m)==0) diff --git a/include/mruby/range.h b/include/mruby/range.h index b166e586b..500a941d5 100644 --- a/include/mruby/range.h +++ b/include/mruby/range.h @@ -14,20 +14,43 @@ */ MRB_BEGIN_DECL +#if defined(MRB_NAN_BOXING) && defined(MRB_64BIT) || defined(MRB_WORD_BOXING) +# define MRB_RANGE_EMBED +#endif + +#ifdef MRB_RANGE_EMBED +struct RRange { + MRB_OBJECT_HEADER; + mrb_value beg; + mrb_value end; + mrb_bool excl; +}; +# define mrb_gc_free_range(mrb, p) ((void)0) +# define RANGE_BEG(p) ((p)->beg) +# define RANGE_END(p) ((p)->end) +#else typedef struct mrb_range_edges { mrb_value beg; mrb_value end; } mrb_range_edges; - struct RRange { MRB_OBJECT_HEADER; mrb_range_edges *edges; - mrb_bool excl : 1; + mrb_bool excl; }; +# define mrb_gc_free_range(mrb, p) mrb_free(mrb, (p)->edges) +# define RANGE_BEG(p) ((p)->edges->beg) +# define RANGE_END(p) ((p)->edges->end) +#endif + +#define mrb_range_beg(mrb, r) RANGE_BEG(mrb_range_ptr(mrb, r)) +#define mrb_range_end(mrb, r) RANGE_END(mrb_range_ptr(mrb, r)) +#define mrb_range_excl_p(mrb, r) RANGE_EXCL(mrb_range_ptr(mrb, r)) +#define mrb_range_raw_ptr(r) ((struct RRange*)mrb_ptr(r)) +#define mrb_range_value(p) mrb_obj_value((void*)(p)) +#define RANGE_EXCL(p) ((p)->excl) -MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v); -#define mrb_range_raw_ptr(v) ((struct RRange*)mrb_ptr(v)) -#define mrb_range_value(p) mrb_obj_value((void*)(p)) +MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value range); /* * Initializes a Range. @@ -41,8 +64,15 @@ MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v); */ MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude); -MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); +enum mrb_range_beg_len { + MRB_RANGE_TYPE_MISMATCH = 0, /* (failure) not range */ + MRB_RANGE_OK = 1, /* (success) range */ + MRB_RANGE_OUT = 2 /* (failure) out of range */ +}; + +MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)); +void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r); MRB_END_DECL diff --git a/include/mruby/string.h b/include/mruby/string.h index 975b1fe0d..77f6becf6 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -39,15 +39,15 @@ struct RString { #define RSTR_UNSET_EMBED_FLAG(s) ((s)->flags &= ~(MRB_STR_EMBED|MRB_STR_EMBED_LEN_MASK)) #define RSTR_SET_EMBED_LEN(s, n) do {\ size_t tmp_n = (n);\ - s->flags &= ~MRB_STR_EMBED_LEN_MASK;\ - s->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\ + (s)->flags &= ~MRB_STR_EMBED_LEN_MASK;\ + (s)->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\ } while (0) #define RSTR_SET_LEN(s, n) do {\ if (RSTR_EMBED_P(s)) {\ RSTR_SET_EMBED_LEN((s),(n));\ }\ else {\ - s->as.heap.len = (mrb_int)(n);\ + (s)->as.heap.len = (mrb_int)(n);\ }\ } while (0) #define RSTR_EMBED_LEN(s)\ @@ -68,6 +68,20 @@ struct RString { #define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE) #define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE) +#ifdef MRB_UTF8_STRING +# define RSTR_ASCII_P(s) ((s)->flags & MRB_STR_ASCII) +# define RSTR_SET_ASCII_FLAG(s) ((s)->flags |= MRB_STR_ASCII) +# define RSTR_UNSET_ASCII_FLAG(s) ((s)->flags &= ~MRB_STR_ASCII) +# define RSTR_WRITE_ASCII_FLAG(s, v) (RSTR_UNSET_ASCII_FLAG(s), (s)->flags |= v) +# define RSTR_COPY_ASCII_FLAG(dst, src) RSTR_WRITE_ASCII_FLAG(dst, RSTR_ASCII_P(src)) +#else +# define RSTR_ASCII_P(s) (void)0 +# define RSTR_SET_ASCII_FLAG(s) (void)0 +# define RSTR_UNSET_ASCII_FLAG(s) (void)0 +# define RSTR_WRITE_ASCII_FLAG(s, v) (void)0 +# 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) @@ -87,13 +101,14 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_FSHARED 2 #define MRB_STR_NOFREE 4 #define MRB_STR_POOL 8 -#define MRB_STR_NO_UTF 16 +#define MRB_STR_ASCII 16 #define MRB_STR_EMBED 32 #define MRB_STR_EMBED_LEN_MASK 0x7c0 #define MRB_STR_EMBED_LEN_SHIFT 6 void mrb_gc_free_str(mrb_state*, struct RString*); -MRB_API void mrb_str_modify(mrb_state*, struct RString*); + +MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s); /* * Finds the index of a substring in a string @@ -102,7 +117,7 @@ MRB_API mrb_int mrb_str_index(mrb_state*, mrb_value, const char*, mrb_int, mrb_i #define mrb_str_index_lit(mrb, str, lit, off) mrb_str_index(mrb, str, lit, mrb_strlen_lit(lit), off); /* - * Appends self to other. Returns self as a concatnated string. + * Appends self to other. Returns self as a concatenated string. * * * Example: @@ -126,10 +141,10 @@ MRB_API mrb_int mrb_str_index(mrb_state*, mrb_value, const char*, mrb_int, mrb_i * str1 = mrb_str_new_lit(mrb, "abc"); * str2 = mrb_str_new_lit(mrb, "def"); * - * // Concatnates str2 to str1. + * // Concatenates str2 to str1. * mrb_str_concat(mrb, str1, str2); * - * // Prints new Concatnated Ruby string. + * // Prints new Concatenated Ruby string. * mrb_p(mrb, str1); * * mrb_close(mrb); @@ -178,10 +193,10 @@ MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value); * mrb_p(mrb, a); * mrb_p(mrb, b); * - * // Concatnates both Ruby strings. + * // Concatenates both Ruby strings. * c = mrb_str_plus(mrb, a, b); * - * // Prints new Concatnated Ruby string. + * // Prints new Concatenated Ruby string. * mrb_p(mrb, c); * * mrb_close(mrb); @@ -193,7 +208,7 @@ MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value); * * => "abc" # First string * => "def" # Second string - * => "abcdef" # First & Second concatnated. + * => "abcdef" # First & Second concatenated. * * @param [mrb_state] mrb The current mruby state. * @param [mrb_value] a First string to concatenate. @@ -311,9 +326,12 @@ MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb * @param [mrb_value] str Ruby string. * @return [mrb_value] A Ruby string. */ +MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str); +MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); +/* obsolete: use mrb_ensure_string_type() instead */ MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str); -MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); + MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa); MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa); @@ -349,10 +367,13 @@ MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str); MRB_API mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self); MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck); +MRB_API mrb_value mrb_cstr_to_inum(mrb_state *mrb, const char *s, mrb_int base, mrb_bool badcheck); MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck); +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. */ MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str); @@ -427,14 +448,25 @@ mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); */ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); -void mrb_noregexp(mrb_state *mrb, mrb_value self); -void mrb_regexp_check(mrb_state *mrb, mrb_value obj); - /* For backward compatibility */ #define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr) #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) #define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2) +mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); +mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); + +MRB_INLINE void +mrb_str_modify(mrb_state *mrb, struct RString *s) +{ + mrb_str_modify_keep_ascii(mrb, s); + RSTR_UNSET_ASCII_FLAG(s); +} + +#ifdef MRB_UTF8_STRING +mrb_int mrb_utf8_len(const char *str, mrb_int byte_len); +#endif + MRB_END_DECL #endif /* MRUBY_STRING_H */ diff --git a/include/mruby/throw.h b/include/mruby/throw.h index 5d3d214e7..4a1fd8d60 100644 --- a/include/mruby/throw.h +++ b/include/mruby/throw.h @@ -15,9 +15,9 @@ #if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus) -#define MRB_TRY(buf) do { try { +#define MRB_TRY(buf) try { #define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; } -#define MRB_END_EXC(buf) } } while(0) +#define MRB_END_EXC(buf) } #define MRB_THROW(buf) throw((buf)->impl) typedef mrb_int mrb_jmpbuf_impl; @@ -34,9 +34,9 @@ typedef mrb_int mrb_jmpbuf_impl; #define MRB_LONGJMP longjmp #endif -#define MRB_TRY(buf) do { if (MRB_SETJMP((buf)->impl) == 0) { +#define MRB_TRY(buf) if (MRB_SETJMP((buf)->impl) == 0) { #define MRB_CATCH(buf) } else { -#define MRB_END_EXC(buf) } } while(0) +#define MRB_END_EXC(buf) } #define MRB_THROW(buf) MRB_LONGJMP((buf)->impl, 1); #define mrb_jmpbuf_impl jmp_buf diff --git a/include/mruby/value.h b/include/mruby/value.h index f988826ca..be3dd397f 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -73,9 +73,6 @@ MRB_API double mrb_float_read(const char*, char**); #endif #if defined _MSC_VER && _MSC_VER < 1900 -# ifndef __cplusplus -# define inline __inline -# endif # include <stdarg.h> MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg); MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...); @@ -157,9 +154,19 @@ typedef void mrb_value; #ifndef mrb_nil_p #define mrb_nil_p(o) (mrb_type(o) == MRB_TT_FALSE && !mrb_fixnum(o)) #endif +#ifndef mrb_false_p +#define mrb_false_p(o) (mrb_type(o) == MRB_TT_FALSE && !!mrb_fixnum(o)) +#endif +#ifndef mrb_true_p +#define mrb_true_p(o) (mrb_type(o) == MRB_TT_TRUE) +#endif #ifndef mrb_bool #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) #endif +#if !defined(MRB_SYMBOL_BITSIZE) +#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT) +#define MRB_SYMBOL_MAX UINT32_MAX +#endif #ifndef MRB_WITHOUT_FLOAT #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) #endif @@ -170,7 +177,6 @@ typedef void mrb_value; #define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR) #define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION) #define mrb_test(o) mrb_bool(o) -MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value); /* * Returns a float in Ruby. @@ -185,7 +191,7 @@ MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) } #endif -static inline mrb_value +MRB_INLINE mrb_value mrb_cptr_value(struct mrb_state *mrb, void *p) { mrb_value v; @@ -204,7 +210,7 @@ MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i) return v; } -static inline mrb_value +MRB_INLINE mrb_value mrb_symbol_value(mrb_sym i) { mrb_value v; @@ -212,7 +218,7 @@ mrb_symbol_value(mrb_sym i) return v; } -static inline mrb_value +MRB_INLINE mrb_value mrb_obj_value(void *p) { mrb_value v; @@ -256,7 +262,7 @@ MRB_INLINE mrb_value mrb_true_value(void) return v; } -static inline mrb_value +MRB_INLINE mrb_value mrb_bool_value(mrb_bool boolean) { mrb_value v; @@ -264,7 +270,7 @@ mrb_bool_value(mrb_bool boolean) return v; } -static inline mrb_value +MRB_INLINE mrb_value mrb_undef_value(void) { mrb_value v; @@ -272,7 +278,10 @@ mrb_undef_value(void) return v; } -#ifdef MRB_USE_ETEXT_EDATA +#if defined(MRB_USE_CUSTOM_RO_DATA_P) +/* If you define `MRB_USE_CUSTOM_RO_DATA_P`, you must implement `mrb_ro_data_p()`. */ +mrb_bool mrb_ro_data_p(const char *p); +#elif defined(MRB_USE_ETEXT_EDATA) #if (defined(__APPLE__) && defined(__MACH__)) #include <mach-o/getsect.h> static inline mrb_bool diff --git a/include/mruby/variable.h b/include/mruby/variable.h index 5fef83faf..ff01e5cc8 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -31,8 +31,6 @@ struct global_entry { mrb_value mrb_vm_special_get(mrb_state*, mrb_sym); void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value); -mrb_value mrb_vm_iv_get(mrb_state*, mrb_sym); -void mrb_vm_iv_set(mrb_state*, mrb_sym, mrb_value); mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); @@ -42,8 +40,8 @@ MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_const_remove(mrb_state*, mrb_value, mrb_sym); -MRB_API mrb_bool mrb_iv_p(mrb_state *mrb, mrb_sym sym); -MRB_API void mrb_iv_check(mrb_state *mrb, mrb_sym sym); +MRB_API mrb_bool mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym sym); +MRB_API void mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym sym); MRB_API mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym); MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); MRB_API mrb_bool mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym); @@ -119,12 +117,14 @@ MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_ MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v); MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym); mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*); +void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod); mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value); mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); +mrb_bool mrb_ident_p(const char *s, mrb_int len); /* GC functions */ void mrb_gc_mark_gv(mrb_state*); @@ -133,6 +133,10 @@ void mrb_gc_mark_iv(mrb_state*, struct RObject*); size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); void mrb_gc_free_iv(mrb_state*, struct RObject*); +/* return non zero to break the loop */ +typedef int (mrb_iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*); +MRB_API void mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p); + MRB_END_DECL #endif /* MRUBY_VARIABLE_H */ diff --git a/include/mruby/version.h b/include/mruby/version.h index 43d6461ea..206078df0 100644 --- a/include/mruby/version.h +++ b/include/mruby/version.h @@ -27,7 +27,7 @@ MRB_BEGIN_DECL /* * The version of Ruby used by mruby. */ -#define MRUBY_RUBY_VERSION "1.9" +#define MRUBY_RUBY_VERSION "2.0" /* * Ruby engine. @@ -37,12 +37,12 @@ MRB_BEGIN_DECL /* * Major release version number. */ -#define MRUBY_RELEASE_MAJOR 1 +#define MRUBY_RELEASE_MAJOR 2 /* * Minor release version number. */ -#define MRUBY_RELEASE_MINOR 4 +#define MRUBY_RELEASE_MINOR 0 /* * Tiny release version number. @@ -62,7 +62,7 @@ MRB_BEGIN_DECL /* * Release year. */ -#define MRUBY_RELEASE_YEAR 2018 +#define MRUBY_RELEASE_YEAR 2019 /* * Release month. @@ -72,12 +72,26 @@ MRB_BEGIN_DECL /* * Release day. */ -#define MRUBY_RELEASE_DAY 27 +#define MRUBY_RELEASE_DAY 4 /* * Release date as a string. */ -#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY) +#define MRUBY_RELEASE_DATE \ + MRUBY_RELEASE_YEAR_STR "-" \ + MRUBY_RELEASE_MONTH_STR "-" \ + MRUBY_RELEASE_DAY_STR +#define MRUBY_RELEASE_YEAR_STR MRB_STRINGIZE(MRUBY_RELEASE_YEAR) +#if MRUBY_RELEASE_MONTH < 10 +#define MRUBY_RELEASE_MONTH_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) +#else +#define MRUBY_RELEASE_MONTH_STR MRB_STRINGIZE(MRUBY_RELEASE_MONTH) +#endif +#if MRUBY_RELEASE_DAY < 10 +#define MRUBY_RELEASE_DAY_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_DAY) +#else +#define MRUBY_RELEASE_DAY_STR MRB_STRINGIZE(MRUBY_RELEASE_DAY) +#endif /* * The year mruby was first created. |
