summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/mrbconf.h95
-rw-r--r--include/mruby.h98
-rw-r--r--include/mruby/array.h20
-rw-r--r--include/mruby/boxing_nan.h2
-rw-r--r--include/mruby/boxing_word.h56
-rw-r--r--include/mruby/class.h37
-rw-r--r--include/mruby/common.h17
-rw-r--r--include/mruby/compile.h19
-rw-r--r--include/mruby/data.h11
-rw-r--r--include/mruby/debug.h10
-rw-r--r--include/mruby/dump.h10
-rw-r--r--include/mruby/error.h2
-rw-r--r--include/mruby/hash.h65
-rw-r--r--include/mruby/irep.h33
-rw-r--r--include/mruby/istruct.h4
-rw-r--r--include/mruby/numeric.h10
-rw-r--r--include/mruby/object.h11
-rw-r--r--include/mruby/opcode.h186
-rw-r--r--include/mruby/ops.h117
-rw-r--r--include/mruby/proc.h17
-rw-r--r--include/mruby/range.h42
-rw-r--r--include/mruby/string.h62
-rw-r--r--include/mruby/throw.h8
-rw-r--r--include/mruby/value.h29
-rw-r--r--include/mruby/variable.h12
-rw-r--r--include/mruby/version.h26
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. |
* | &vert; | 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.