summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/compile.h2
-rw-r--r--include/mruby/hash.h8
-rw-r--r--include/mruby/irep.h6
-rw-r--r--include/mruby/object.h5
-rw-r--r--include/mruby/proc.h8
-rw-r--r--include/mruby/string.h5
-rw-r--r--include/mruby/value.h2
-rw-r--r--include/mruby/variable.h12
-rw-r--r--mrbgems/mruby-fiber/src/fiber.c2
-rw-r--r--mrbgems/mruby-proc-ext/src/proc.c43
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c8
-rw-r--r--mrbgems/mruby-string-utf8/src/string.c29
-rw-r--r--mrbgems/mruby-struct/src/struct.c54
-rw-r--r--mrblib/class.rb23
-rw-r--r--src/class.c117
-rw-r--r--src/codegen.c74
-rw-r--r--src/dump.c89
-rw-r--r--src/error.c2
-rw-r--r--src/gc.c14
-rw-r--r--src/hash.c26
-rw-r--r--src/kernel.c88
-rw-r--r--src/load.c86
-rw-r--r--src/numeric.c2
-rw-r--r--src/parse.y404
-rw-r--r--src/pool.c10
-rw-r--r--src/proc.c72
-rw-r--r--src/state.c2
-rw-r--r--src/string.c37
-rw-r--r--src/symbol.c19
-rw-r--r--src/variable.c32
-rw-r--r--src/vm.c17
31 files changed, 735 insertions, 563 deletions
diff --git a/include/mruby/compile.h b/include/mruby/compile.h
index 5efdef213..a85939998 100644
--- a/include/mruby/compile.h
+++ b/include/mruby/compile.h
@@ -29,6 +29,7 @@ typedef struct mrbc_context {
mrb_bool dump_result:1;
mrb_bool no_exec:1;
mrb_bool keep_lv:1;
+ mrb_bool no_optimize:1;
} mrbc_context;
mrbc_context* mrbc_context_new(mrb_state *mrb);
@@ -143,6 +144,7 @@ struct mrb_parser_state {
size_t nwarn;
mrb_ast_node *tree;
+ mrb_bool no_optimize:1;
mrb_bool capture_errors:1;
struct mrb_parser_message error_buffer[10];
struct mrb_parser_message warn_buffer[10];
diff --git a/include/mruby/hash.h b/include/mruby/hash.h
index dbad3e1fc..5339312c6 100644
--- a/include/mruby/hash.h
+++ b/include/mruby/hash.h
@@ -21,7 +21,7 @@ struct RHash {
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
MRB_API mrb_value mrb_hash_new_capa(mrb_state*, int);
-mrb_value mrb_hash_new(mrb_state *mrb);
+MRB_API mrb_value mrb_hash_new(mrb_state *mrb);
MRB_API void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val);
MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key);
@@ -43,9 +43,9 @@ MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);
#define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT)
/* GC functions */
-MRB_API void mrb_gc_mark_hash(mrb_state*, struct RHash*);
-MRB_API size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*);
-MRB_API void mrb_gc_free_hash(mrb_state*, struct RHash*);
+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*);
#if defined(__cplusplus)
} /* extern "C" { */
diff --git a/include/mruby/irep.h b/include/mruby/irep.h
index 766431e2c..f4061bb54 100644
--- a/include/mruby/irep.h
+++ b/include/mruby/irep.h
@@ -49,9 +49,9 @@ typedef struct mrb_irep {
MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*);
-MRB_API void mrb_irep_free(mrb_state*, struct mrb_irep*);
-MRB_API void mrb_irep_incref(mrb_state*, struct mrb_irep*);
-MRB_API void mrb_irep_decref(mrb_state*, struct mrb_irep*);
+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*);
#if defined(__cplusplus)
} /* extern "C" { */
diff --git a/include/mruby/object.h b/include/mruby/object.h
index 56917a021..fe55620fe 100644
--- a/include/mruby/object.h
+++ b/include/mruby/object.h
@@ -37,16 +37,13 @@ struct RBasic {
MRB_OBJECT_HEADER;
};
#define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v)))
-/* obsolete macro mrb_basic; will be removed soon */
-#define mrb_basic(v) mrb_basic_ptr(v)
struct RObject {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
};
#define mrb_obj_ptr(v) ((struct RObject*)(mrb_ptr(v)))
-/* obsolete macro mrb_object; will be removed soon */
-#define mrb_object(o) mrb_obj_ptr(o)
+
#define mrb_immediate_p(x) (mrb_type(x) < MRB_TT_HAS_BASIC)
#define mrb_special_const_p(x) mrb_immediate_p(x)
diff --git a/include/mruby/proc.h b/include/mruby/proc.h
index 9c25c9c46..fe5a1d2f6 100644
--- a/include/mruby/proc.h
+++ b/include/mruby/proc.h
@@ -54,14 +54,16 @@ struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
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);
-MRB_API void mrb_proc_copy(struct RProc *a, struct RProc *b);
+void mrb_proc_copy(struct RProc *a, struct RProc *b);
/* implementation of #send method */
-mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
+MRB_API 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*);
-MRB_API mrb_value mrb_cfunc_env_get(mrb_state*, mrb_int);
+MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int);
+/* old name */
+#define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx)
#include "mruby/khash.h"
KHASH_DECLARE(mt, mrb_sym, struct RProc*, TRUE)
diff --git a/include/mruby/string.h b/include/mruby/string.h
index 0bd4cfc0f..5228dcbca 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -74,7 +74,7 @@ mrb_int mrb_str_strlen(mrb_state*, struct RString*);
#define MRB_STR_EMBED_LEN_MASK 0xf8
#define MRB_STR_EMBED_LEN_SHIFT 3
-MRB_API void mrb_gc_free_str(mrb_state*, struct RString*);
+void mrb_gc_free_str(mrb_state*, struct RString*);
MRB_API void mrb_str_modify(mrb_state*, struct RString*);
MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
MRB_API mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
@@ -107,6 +107,9 @@ mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str);
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)
diff --git a/include/mruby/value.h b/include/mruby/value.h
index b1278e3a3..859687ffc 100644
--- a/include/mruby/value.h
+++ b/include/mruby/value.h
@@ -7,7 +7,7 @@
#ifndef MRUBY_VALUE_H
#define MRUBY_VALUE_H
-typedef short mrb_sym;
+typedef uint16_t mrb_sym;
typedef uint8_t mrb_bool;
struct mrb_state;
diff --git a/include/mruby/variable.h b/include/mruby/variable.h
index 0851a05bb..8758114b9 100644
--- a/include/mruby/variable.h
+++ b/include/mruby/variable.h
@@ -39,6 +39,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 mrb_bool mrb_iv_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);
@@ -66,11 +68,11 @@ mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym);
mrb_sym mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer);
/* GC functions */
-MRB_API void mrb_gc_mark_gv(mrb_state*);
-MRB_API void mrb_gc_free_gv(mrb_state*);
-MRB_API void mrb_gc_mark_iv(mrb_state*, struct RObject*);
-MRB_API size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*);
-MRB_API void mrb_gc_free_iv(mrb_state*, struct RObject*);
+void mrb_gc_mark_gv(mrb_state*);
+void mrb_gc_free_gv(mrb_state*);
+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*);
#if defined(__cplusplus)
} /* extern "C" { */
diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c
index 7b4ddfb11..de4901a87 100644
--- a/mrbgems/mruby-fiber/src/fiber.c
+++ b/mrbgems/mruby-fiber/src/fiber.c
@@ -291,7 +291,7 @@ fiber_transfer(mrb_state *mrb, mrb_value self)
return fiber_switch(mrb, self, len, a, FALSE);
}
-mrb_value
+MRB_API mrb_value
mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a)
{
struct mrb_context *c = mrb->c;
diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c
index 14b68547e..73873a360 100644
--- a/mrbgems/mruby-proc-ext/src/proc.c
+++ b/mrbgems/mruby-proc-ext/src/proc.c
@@ -5,49 +5,6 @@
#include "mruby/string.h"
#include "mruby/debug.h"
-MRB_API struct RProc *
-mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t f, mrb_int argc, const mrb_value *argv)
-{
- struct RProc *p;
- struct REnv *e;
- int ai, i;
-
- p = mrb_proc_new_cfunc(mrb, f);
- ai = mrb_gc_arena_save(mrb);
- e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
- p->env = e;
- mrb_gc_arena_restore(mrb, ai);
-
- MRB_ENV_UNSHARE_STACK(e);
- MRB_ENV_STACK_LEN(e) = argc;
- e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
- for (i = 0; i < argc; ++i) {
- e->stack[i] = argv[i];
- }
-
- return p;
-}
-
-MRB_API mrb_value
-mrb_cfunc_env_get(mrb_state *mrb, mrb_int idx)
-{
- struct RProc *p = mrb->c->ci->proc;
- struct REnv *e = p->env;
-
- if (!MRB_PROC_CFUNC_P(p)) {
- mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc.");
- }
- if (!e) {
- mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv.");
- }
- if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) {
- mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)",
- mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));
- }
-
- return e->stack[idx];
-}
-
static mrb_value
mrb_proc_lambda(mrb_state *mrb, mrb_value self)
{
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index 3fce60237..d88e242c6 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -178,17 +178,18 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
}
#define GETASTER(num) do { \
+ mrb_value tmp_v; \
t = p++; \
n = 0; \
GETNUM(n, val); \
if (*p == '$') { \
- tmp = GETPOSARG(n); \
+ tmp_v = GETPOSARG(n); \
} \
else { \
- tmp = GETARG(); \
+ tmp_v = GETARG(); \
p = t; \
} \
- num = mrb_fixnum(tmp); \
+ num = mrb_fixnum(tmp_v); \
} while (0)
static mrb_value
@@ -500,7 +501,6 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
int nextarg = 1;
int posarg = 0;
mrb_value nextvalue;
- mrb_value tmp;
mrb_value str;
mrb_value hash = mrb_undef_value();
diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c
index a1b779f95..b232df1c5 100644
--- a/mrbgems/mruby-string-utf8/src/string.c
+++ b/mrbgems/mruby-string-utf8/src/string.c
@@ -106,21 +106,6 @@ mrb_str_size(mrb_state *mrb, mrb_value str)
#define RSTRING_LEN_UTF8(s) mrb_utf8_strlen(s, -1)
-static mrb_value
-noregexp(mrb_state *mrb, mrb_value self)
-{
- mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented");
- return mrb_nil_value();
-}
-
-static void
-regexp_check(mrb_state *mrb, mrb_value obj)
-{
- if (mrb_regexp_p(mrb, obj)) {
- noregexp(mrb, obj);
- }
-}
-
static inline mrb_int
mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n)
{
@@ -270,7 +255,7 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
{
mrb_int idx;
- regexp_check(mrb, indx);
+ mrb_regexp_check(mrb, indx);
switch (mrb_type(indx)) {
case MRB_TT_FIXNUM:
idx = mrb_fixnum(indx);
@@ -315,7 +300,7 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str)
argc = mrb_get_args(mrb, "o|o", &a1, &a2);
if (argc == 2) {
- regexp_check(mrb, a1);
+ mrb_regexp_check(mrb, a1);
return str_substr(mrb, str, mrb_fixnum(a1), mrb_fixnum(a2));
}
if (argc != 1) {
@@ -346,7 +331,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
sub = mrb_nil_value();
}
- regexp_check(mrb, sub);
+ mrb_regexp_check(mrb, sub);
if (pos < 0) {
pos += RSTRING_LEN(str);
if (pos < 0) {
@@ -425,7 +410,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
if (pos < 0) {
pos += len;
if (pos < 0) {
- regexp_check(mrb, sub);
+ mrb_regexp_check(mrb, sub);
return mrb_nil_value();
}
}
@@ -438,7 +423,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
else
sub = mrb_nil_value();
}
- regexp_check(mrb, sub);
+ mrb_regexp_check(mrb, sub);
if (mrb_type(sub) == MRB_TT_FIXNUM) {
sub = mrb_fixnum_chr(mrb, sub);
@@ -548,7 +533,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
}
}
else {
- noregexp(mrb, str);
+ mrb_noregexp(mrb, str);
}
}
@@ -618,7 +603,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
beg = ptr - temp;
}
else {
- noregexp(mrb, str);
+ mrb_noregexp(mrb, str);
}
if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
if (RSTRING_LEN(str) == beg) {
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index 930384806..415a8a1d6 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -224,14 +224,37 @@ is_const_id(mrb_state *mrb, const char *name)
return ISUPPER(name[0]);
}
+static void
+make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c)
+{
+ mrb_value *ptr_members = RARRAY_PTR(members);
+ mrb_int i;
+ mrb_int len = RARRAY_LEN(members);
+ int ai = mrb_gc_arena_save(mrb);
+
+ for (i=0; i<len; i++) {
+ mrb_sym id = mrb_symbol(ptr_members[i]);
+ const char *name = mrb_sym2name_len(mrb, id, NULL);
+
+ if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
+ if (i < N_REF_FUNC) {
+ mrb_define_method_id(mrb, c, id, ref_func[i], MRB_ARGS_NONE());
+ }
+ else {
+ mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE());
+ }
+ mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1));
+ mrb_gc_arena_restore(mrb, ai);
+ }
+ }
+}
+
static mrb_value
make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass)
{
- mrb_value nstr, *ptr_members;
+ mrb_value nstr;
mrb_sym id;
- mrb_int i, len;
struct RClass *c;
- int ai;
if (mrb_nil_p(name)) {
c = mrb_class_new(mrb, klass);
@@ -257,24 +280,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k
mrb_define_class_method(mrb, c, "[]", mrb_instance_new, MRB_ARGS_ANY());
mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, MRB_ARGS_NONE());
/* RSTRUCT(nstr)->basic.c->super = c->c; */
- ptr_members = RARRAY_PTR(members);
- len = RARRAY_LEN(members);
- ai = mrb_gc_arena_save(mrb);
- for (i=0; i< len; i++) {
- mrb_sym id = mrb_symbol(ptr_members[i]);
- const char *name = mrb_sym2name_len(mrb, id, NULL);
-
- if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
- if (i < N_REF_FUNC) {
- mrb_define_method_id(mrb, c, id, ref_func[i], MRB_ARGS_NONE());
- }
- else {
- mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE());
- }
- mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1));
- mrb_gc_arena_restore(mrb, ai);
- }
- }
+ make_struct_define_accessors(mrb, members, c);
return nstr;
}
@@ -432,7 +438,7 @@ inspect_struct(mrb_state *mrb, mrb_value s, mrb_bool recur)
mrb_value slot;
mrb_sym id;
const char *name;
- mrb_int len;
+ mrb_int namelen;
if (i > 0) {
mrb_str_cat_lit(mrb, str, ", ");
@@ -442,9 +448,9 @@ inspect_struct(mrb_state *mrb, mrb_value s, mrb_bool recur)
}
slot = ptr_members[i];
id = mrb_symbol(slot);
- name = mrb_sym2name_len(mrb, id, &len);
+ name = mrb_sym2name_len(mrb, id, &namelen);
if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
- mrb_str_append(mrb, str, mrb_str_new(mrb, name, len));
+ mrb_str_append(mrb, str, mrb_str_new(mrb, name, namelen));
}
else {
mrb_str_append(mrb, str, mrb_inspect(mrb, slot));
diff --git a/mrblib/class.rb b/mrblib/class.rb
index ebfb1f76d..39e0d5091 100644
--- a/mrblib/class.rb
+++ b/mrblib/class.rb
@@ -1,26 +1,5 @@
class Module
- # 15.2.2.4.13
- def attr_reader(*names)
- names.each do |name|
- name = name.to_s
- raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$')
-
- attr_name = '@'+name
- define_method(name){self.instance_variable_get(attr_name)}
- end
- end
- # 15.2.2.4.14
- def attr_writer(*names)
- names.each do |name|
- name = name.to_s
- raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$')
-
- attr_name = '@'+name
- name = (name+"=").intern
- define_method(name){|v|self.instance_variable_set(attr_name,v)}
- end
- end
- # 15.2.2.4.12
+ # 15.2.2.4.12
def attr_accessor(*names)
attr_reader(*names)
attr_writer(*names)
diff --git a/src/class.c b/src/class.c
index d3a2403f1..c11346223 100644
--- a/src/class.c
+++ b/src/class.c
@@ -393,6 +393,21 @@ to_hash(mrb_state *mrb, mrb_value val)
return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash");
}
+static mrb_sym
+to_sym(mrb_state *mrb, mrb_value ss)
+{
+ if (mrb_type(ss) == MRB_TT_SYMBOL) {
+ return mrb_symbol(ss);
+ }
+ else if (mrb_string_p(ss)) {
+ return mrb_intern_str(mrb, to_str(mrb, ss));
+ }
+ else {
+ mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0);
+ mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj);
+ }
+}
+
/*
retrieve arguments from mrb_state.
@@ -635,16 +650,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value ss;
ss = *sp++;
- if (mrb_type(ss) == MRB_TT_SYMBOL) {
- *symp = mrb_symbol(ss);
- }
- else if (mrb_string_p(ss)) {
- *symp = mrb_intern_str(mrb, to_str(mrb, ss));
- }
- else {
- mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0);
- mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj);
- }
+ *symp = to_sym(mrb, ss);
i++;
}
}
@@ -958,7 +964,7 @@ mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
return mod;
}
-mrb_value
+MRB_API mrb_value
mrb_singleton_class(mrb_state *mrb, mrb_value v)
{
struct RBasic *obj;
@@ -1051,6 +1057,91 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
}
static mrb_value
+attr_reader(mrb_state *mrb, mrb_value obj)
+{
+ mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
+ return mrb_iv_get(mrb, obj, to_sym(mrb, name));
+}
+
+static mrb_value
+mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
+{
+ struct RClass *c = mrb_class_ptr(mod);
+ mrb_value *argv;
+ mrb_int argc, i;
+ int ai;
+
+ mrb_get_args(mrb, "*", &argv, &argc);
+ ai = mrb_gc_arena_save(mrb);
+ for (i=0; i<argc; i++) {
+ mrb_value name, str;
+ mrb_sym method, sym;
+
+ method = to_sym(mrb, argv[i]);
+ name = mrb_sym2str(mrb, method);
+ str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1);
+ mrb_str_cat_lit(mrb, str, "@");
+ mrb_str_cat_str(mrb, str, name);
+ sym = mrb_intern_str(mrb, str);
+ mrb_iv_check(mrb, sym);
+ name = mrb_symbol_value(sym);
+ mrb_define_method_raw(mrb, c, method,
+ mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name));
+ mrb_gc_arena_restore(mrb, ai);
+ }
+ return mrb_nil_value();
+}
+
+static mrb_value
+attr_writer(mrb_state *mrb, mrb_value obj)
+{
+ mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
+ mrb_value val;
+
+ mrb_get_args(mrb, "o", &val);
+ mrb_iv_set(mrb, obj, to_sym(mrb, name), val);
+ return val;
+}
+
+static mrb_value
+mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
+{
+ struct RClass *c = mrb_class_ptr(mod);
+ mrb_value *argv;
+ mrb_int argc, i;
+ int ai;
+
+ mrb_get_args(mrb, "*", &argv, &argc);
+ ai = mrb_gc_arena_save(mrb);
+ for (i=0; i<argc; i++) {
+ mrb_value name, str, attr;
+ mrb_sym method, sym;
+
+ method = to_sym(mrb, argv[i]);
+
+ /* prepare iv name (@name) */
+ name = mrb_sym2str(mrb, method);
+ str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1);
+ mrb_str_cat_lit(mrb, str, "@");
+ mrb_str_cat_str(mrb, str, name);
+ sym = mrb_intern_str(mrb, str);
+ mrb_iv_check(mrb, sym);
+ attr = mrb_symbol_value(sym);
+
+ /* prepare method name (name=) */
+ str = mrb_str_buf_new(mrb, RSTRING_LEN(str));
+ mrb_str_cat_str(mrb, str, name);
+ mrb_str_cat_lit(mrb, str, "=");
+ method = mrb_intern_str(mrb, str);
+
+ mrb_define_method_raw(mrb, c, method,
+ mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr));
+ mrb_gc_arena_restore(mrb, ai);
+ }
+ return mrb_nil_value();
+}
+
+static mrb_value
mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
{
struct RClass *c = mrb_class_ptr(cv);
@@ -1409,7 +1500,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
* \param name1 a new name for the method
* \param name2 the original name of the method
*/
-void
+MRB_API void
mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
{
mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
@@ -2033,6 +2124,8 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */
mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
+ mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */
+ mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */
mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE());
mrb_define_method(mrb, mod, "inspect", mrb_mod_to_s, MRB_ARGS_NONE());
mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */
diff --git a/src/codegen.c b/src/codegen.c
index b2b1e4150..e6f277b1b 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -81,7 +81,7 @@ static struct loopinfo *loop_push(codegen_scope *s, enum looptype t);
static void loop_break(codegen_scope *s, node *tree);
static void loop_pop(codegen_scope *s, int val);
-static void gen_assignment(codegen_scope *s, node *node, int sp, int val);
+static void gen_assignment(codegen_scope *s, node *tree, int sp, int val);
static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val);
static void codegen(codegen_scope *s, node *tree, int val);
@@ -162,11 +162,19 @@ genop(codegen_scope *s, mrb_code i)
#define NOVAL 0
#define VAL 1
+static mrb_bool
+no_optimize(codegen_scope *s)
+{
+ if (s && s->parser && s->parser->no_optimize)
+ return TRUE;
+ return FALSE;
+}
+
static int
genop_peep(codegen_scope *s, mrb_code i, int val)
{
/* peephole optimization */
- if (s->lastlabel != s->pc && s->pc > 0) {
+ if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) {
mrb_code i0 = s->iseq[s->pc-1];
int c1 = GET_OPCODE(i);
int c0 = GET_OPCODE(i0);
@@ -180,13 +188,13 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
if (val) break;
switch (c0) {
case OP_MOVE:
- if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0) && GETARG_A(i) >= s->nlocals) {
+ if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) {
/* skip swapping OP_MOVE */
return 0;
}
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
- s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0));
- return 0;
+ s->pc--;
+ return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val);
}
break;
case OP_LOADI:
@@ -319,10 +327,9 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
}
case OP_STRCAT:
if (c0 == OP_STRING) {
- int i = GETARG_Bx(i0);
+ mrb_value v = s->irep->pool[GETARG_Bx(i0)];
- if (mrb_type(s->irep->pool[i]) == MRB_TT_STRING &&
- RSTRING_LEN(s->irep->pool[i]) == 0) {
+ if (mrb_string_p(v) && RSTRING_LEN(v) == 0) {
s->pc--;
return 0;
}
@@ -837,34 +844,34 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
push();pop();
pop_n(n+1);
{
- mrb_int len;
- const char *name = mrb_sym2name_len(s->mrb, sym, &len);
+ mrb_int symlen;
+ const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen);
- if (!noop && len == 1 && name[0] == '+') {
+ if (!noop && symlen == 1 && symname[0] == '+') {
genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val);
}
- else if (!noop && len == 1 && name[0] == '-') {
+ else if (!noop && symlen == 1 && symname[0] == '-') {
genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val);
}
- else if (!noop && len == 1 && name[0] == '*') {
+ else if (!noop && symlen == 1 && symname[0] == '*') {
genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n));
}
- else if (!noop && len == 1 && name[0] == '/') {
+ else if (!noop && symlen == 1 && symname[0] == '/') {
genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n));
}
- else if (!noop && len == 1 && name[0] == '<') {
+ else if (!noop && symlen == 1 && symname[0] == '<') {
genop(s, MKOP_ABC(OP_LT, cursp(), idx, n));
}
- else if (!noop && len == 2 && name[0] == '<' && name[1] == '=') {
+ else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=') {
genop(s, MKOP_ABC(OP_LE, cursp(), idx, n));
}
- else if (!noop && len == 1 && name[0] == '>') {
+ else if (!noop && symlen == 1 && symname[0] == '>') {
genop(s, MKOP_ABC(OP_GT, cursp(), idx, n));
}
- else if (!noop && len == 2 && name[0] == '>' && name[1] == '=') {
+ else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=') {
genop(s, MKOP_ABC(OP_GE, cursp(), idx, n));
}
- else if (!noop && len == 2 && name[0] == '=' && name[1] == '=') {
+ else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=') {
genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n));
}
else {
@@ -883,19 +890,19 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
}
static void
-gen_assignment(codegen_scope *s, node *node, int sp, int val)
+gen_assignment(codegen_scope *s, node *tree, int sp, int val)
{
int idx;
- int type = (intptr_t)node->car;
+ int type = (intptr_t)tree->car;
- node = node->cdr;
+ tree = tree->cdr;
switch ((intptr_t)type) {
case NODE_GVAR:
- idx = new_sym(s, sym(node));
+ idx = new_sym(s, sym(tree));
genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val);
break;
case NODE_LVAR:
- idx = lv_idx(s, sym(node));
+ idx = lv_idx(s, sym(tree));
if (idx > 0) {
if (idx != sp) {
genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val);
@@ -907,7 +914,7 @@ gen_assignment(codegen_scope *s, node *node, int sp, int val)
codegen_scope *up = s->prev;
while (up) {
- idx = lv_idx(up, sym(node));
+ idx = lv_idx(up, sym(tree));
if (idx > 0) {
genop_peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val);
break;
@@ -918,29 +925,29 @@ gen_assignment(codegen_scope *s, node *node, int sp, int val)
}
break;
case NODE_IVAR:
- idx = new_sym(s, sym(node));
+ idx = new_sym(s, sym(tree));
genop_peep(s, MKOP_ABx(OP_SETIV, sp, idx), val);
break;
case NODE_CVAR:
- idx = new_sym(s, sym(node));
+ idx = new_sym(s, sym(tree));
genop_peep(s, MKOP_ABx(OP_SETCV, sp, idx), val);
break;
case NODE_CONST:
- idx = new_sym(s, sym(node));
+ idx = new_sym(s, sym(tree));
genop_peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val);
break;
case NODE_COLON2:
- idx = new_sym(s, sym(node->cdr));
+ idx = new_sym(s, sym(tree->cdr));
genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL);
push();
- codegen(s, node->car, VAL);
+ codegen(s, tree->car, VAL);
pop_n(2);
genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val);
break;
case NODE_CALL:
push();
- gen_call(s, node, attrsym(s, sym(node->cdr->car)), sp, NOVAL);
+ gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL);
pop();
if (val) {
genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);
@@ -2225,7 +2232,6 @@ codegen(codegen_scope *s, node *tree, int val)
}
if (n->cdr) {
char *p2 = (char*)n->cdr;
- int off;
push();
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
@@ -2299,7 +2305,7 @@ codegen(codegen_scope *s, node *tree, int val)
{
int a = new_msym(s, sym(tree->car));
int b = new_msym(s, sym(tree->cdr));
- int c = new_msym(s, mrb_intern_lit(s->mrb,"alias_method"));
+ int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method"));
genop(s, MKOP_A(OP_TCLASS, cursp()));
push();
@@ -3106,7 +3112,7 @@ mrb_codedump_all(mrb_state *mrb, struct RProc *proc)
codedump_recur(mrb, proc->body.irep);
}
-struct RProc*
+MRB_API struct RProc*
mrb_generate_code(mrb_state *mrb, parser_state *p)
{
codegen_scope *scope = scope_new(mrb, 0, 0);
diff --git a/src/dump.c b/src/dump.c
index e019baa99..0ea4e5afe 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -13,6 +13,9 @@
#include "mruby/numeric.h"
#include "mruby/debug.h"
+#define FLAG_BYTEORDER_NATIVE 2
+#define FLAG_BYTEORDER_NONATIVE 0
+
#ifdef ENABLE_STDIO
static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep);
@@ -58,14 +61,20 @@ get_iseq_block_size(mrb_state *mrb, mrb_irep *irep)
}
static ptrdiff_t
-write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
+write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags)
{
uint8_t *cur = buf;
uint32_t iseq_no;
cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */
- for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
- cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
+ if (flags & FLAG_BYTEORDER_NATIVE) {
+ memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code));
+ cur += irep->ilen * sizeof(mrb_code);
+ }
+ else {
+ for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
+ cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
+ }
}
return cur - buf;
@@ -263,7 +272,7 @@ get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
}
static int
-write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size)
+write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size, uint8_t flags)
{
uint32_t i;
@@ -279,7 +288,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec
memset(bin, 0, *irep_record_size);
bin += write_irep_header(mrb, irep, bin);
- bin += write_iseq_block(mrb, irep, bin);
+ bin += write_iseq_block(mrb, irep, bin, flags);
bin += write_pool_block(mrb, irep, bin);
bin += write_syms_block(mrb, irep, bin);
@@ -287,7 +296,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec
int result;
size_t rsize;
- result = write_irep_record(mrb, irep->reps[i], bin, &rsize);
+ result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags);
if (result != MRB_DUMP_OK) {
return result;
}
@@ -325,7 +334,7 @@ write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin)
}
static int
-write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
+write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, uint8_t flags)
{
int result;
size_t section_size = 0; /* size of irep record */
@@ -339,7 +348,7 @@ write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
cur += sizeof(struct rite_section_irep_header);
section_size += sizeof(struct rite_section_irep_header);
- result = write_irep_record(mrb, irep, cur, &rsize);
+ result = write_irep_record(mrb, irep, cur, &rsize, flags);
if (result != MRB_DUMP_OK) {
return result;
}
@@ -795,13 +804,25 @@ lv_section_exit:
}
static int
-write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin)
+write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags)
{
struct rite_binary_header *header = (struct rite_binary_header *)bin;
uint16_t crc;
uint32_t offset;
- memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify));
+ if (flags & FLAG_BYTEORDER_NATIVE) {
+ uint32_t ident = 0;
+ size_t i;
+
+ for(i=0; i<sizeof(ident); i++) {
+ ident<<=8;
+ ident|=RITE_BINARY_IDENTIFIER[i];
+ }
+ memcpy(header->binary_identify, (char*)&ident, sizeof(uint32_t));
+ }
+ else {
+ memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify));
+ }
memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version));
memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name));
memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version));
@@ -841,8 +862,8 @@ is_lv_defined(mrb_irep *irep)
return FALSE;
}
-int
-mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size)
+static int
+dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size, uint8_t flags)
{
int result = MRB_DUMP_GENERAL_FAILURE;
size_t section_irep_size;
@@ -889,12 +910,9 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
section_irep_size + section_lineno_size + section_lv_size +
sizeof(struct rite_binary_footer);
cur = *bin = (uint8_t*)mrb_malloc(mrb, *bin_size);
- if (cur == NULL) {
- goto error_exit;
- }
cur += sizeof(struct rite_binary_header);
- result = write_section_irep(mrb, irep, cur);
+ result = write_section_irep(mrb, irep, cur, flags);
if (result != MRB_DUMP_OK) {
goto error_exit;
}
@@ -923,7 +941,7 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
}
write_footer(mrb, cur);
- write_rite_binary_header(mrb, *bin_size, *bin);
+ write_rite_binary_header(mrb, *bin_size, *bin, flags);
error_exit:
if (result != MRB_DUMP_OK) {
@@ -940,6 +958,12 @@ error_exit:
}
int
+mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size)
+{
+ return dump_irep(mrb, irep, debug_info, bin, bin_size, FLAG_BYTEORDER_NONATIVE);
+}
+
+int
mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp)
{
uint8_t *bin = NULL;
@@ -950,7 +974,7 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp)
return MRB_DUMP_INVALID_ARGUMENT;
}
- result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size);
+ result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NONATIVE);
if (result == MRB_DUMP_OK) {
if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) {
result = MRB_DUMP_WRITE_FAULT;
@@ -988,15 +1012,32 @@ mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, co
return MRB_DUMP_INVALID_ARGUMENT;
}
- result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size);
+ result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NATIVE);
if (result == MRB_DUMP_OK) {
- fprintf(fp, "#include <stdint.h>\n"); /* for uint8_t under at least Darwin */
- fprintf(fp, "const uint8_t %s[] = {", initname);
+ if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */
+ mrb_free(mrb, bin);
+ return MRB_DUMP_WRITE_FAULT;
+ }
+ if (fprintf(fp, "const uint8_t %s[] = {", initname) < 0) {
+ mrb_free(mrb, bin);
+ return MRB_DUMP_WRITE_FAULT;
+ }
while (bin_idx < bin_size) {
- if (bin_idx % 16 == 0) fputs("\n", fp);
- fprintf(fp, "0x%02x,", bin[bin_idx++]);
+ if (bin_idx % 16 == 0) {
+ if (fputs("\n", fp) == EOF) {
+ mrb_free(mrb, bin);
+ return MRB_DUMP_WRITE_FAULT;
+ }
+ }
+ if (fprintf(fp, "0x%02x,", bin[bin_idx++]) < 0) {
+ mrb_free(mrb, bin);
+ return MRB_DUMP_WRITE_FAULT;
+ }
+ }
+ if (fputs("\n};\n", fp) == EOF) {
+ mrb_free(mrb, bin);
+ return MRB_DUMP_WRITE_FAULT;
}
- fputs("\n};\n", fp);
}
mrb_free(mrb, bin);
diff --git a/src/error.c b/src/error.c
index fa1fcb9b7..0a1a97a0b 100644
--- a/src/error.c
+++ b/src/error.c
@@ -261,7 +261,7 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap)
else {
size = p - b;
mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
- return mrb_ary_join(mrb, ary, mrb_str_new(mrb,NULL,0));
+ return mrb_ary_join(mrb, ary, mrb_str_new(mrb, NULL, 0));
}
}
diff --git a/src/gc.c b/src/gc.c
index 253128a44..4c50b11da 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -227,11 +227,9 @@ mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
nelem <= SIZE_MAX / len) {
size_t size;
size = nelem * len;
- p = mrb_realloc(mrb, 0, size);
+ p = mrb_malloc(mrb, size);
- if (p) {
- memset(p, 0, size);
- }
+ memset(p, 0, size);
}
else {
p = NULL;
@@ -587,7 +585,7 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
}
}
-void
+MRB_API void
mrb_gc_mark(mrb_state *mrb, struct RBasic *obj)
{
if (obj == 0) return;
@@ -1368,7 +1366,7 @@ test_mrb_field_write_barrier(void)
obj = mrb_basic_ptr(mrb_ary_new(mrb));
value = mrb_basic_ptr(mrb_str_new_lit(mrb, "value"));
paint_black(obj);
- paint_partial_white(mrb,value);
+ paint_partial_white(mrb, value);
puts(" in GC_STATE_MARK");
@@ -1379,7 +1377,7 @@ test_mrb_field_write_barrier(void)
puts(" in GC_STATE_SWEEP");
- paint_partial_white(mrb,value);
+ paint_partial_white(mrb, value);
mrb->gc_state = GC_STATE_SWEEP;
mrb_field_write_barrier(mrb, obj, value);
@@ -1390,7 +1388,7 @@ test_mrb_field_write_barrier(void)
puts(" fail with black");
mrb->gc_state = GC_STATE_MARK;
paint_white(obj);
- paint_partial_white(mrb,value);
+ paint_partial_white(mrb, value);
mrb_field_write_barrier(mrb, obj, value);
mrb_assert(obj->color & mrb->current_white_part);
diff --git a/src/hash.c b/src/hash.c
index a43e8ae19..aa0322c8c 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -36,20 +36,20 @@ mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
case MRB_TT_SYMBOL:
h = (khint_t)mrb_symbol(key);
- return kh_int_hash_func(mrb,h);
+ return kh_int_hash_func(mrb, h);
case MRB_TT_FIXNUM:
h = (khint_t)mrb_float_id((mrb_float)mrb_fixnum(key));
- return kh_int_hash_func(mrb,h);
+ return kh_int_hash_func(mrb, h);
case MRB_TT_FLOAT:
h = (khint_t)mrb_float_id(mrb_float(key));
- return kh_int_hash_func(mrb,h);
+ return kh_int_hash_func(mrb, h);
default:
hv = mrb_funcall(mrb, key, "hash", 0);
h = (khint_t)t ^ mrb_fixnum(hv);
- return kh_int_hash_func(mrb,h);
+ return kh_int_hash_func(mrb, h);
}
}
@@ -241,11 +241,11 @@ mrb_hash_dup(mrb_state *mrb, mrb_value hash)
ret_h = ret->ht;
for (k = kh_begin(h); k != kh_end(h); k++) {
- if (kh_exist(h,k)) {
+ if (kh_exist(h, k)) {
int ai = mrb_gc_arena_save(mrb);
- ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h,k)));
+ ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k)));
mrb_gc_arena_restore(mrb, ai);
- kh_val(ret_h, ret_k) = kh_val(h,k);
+ kh_val(ret_h, ret_k) = kh_val(h, k);
}
}
}
@@ -555,9 +555,9 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
mrb_hash_modify(mrb, hash);
if (h && kh_size(h) > 0) {
for (k = kh_begin(h); k != kh_end(h); k++) {
- if (!kh_exist(h,k)) continue;
+ if (!kh_exist(h, k)) continue;
- delKey = kh_key(h,k);
+ delKey = kh_key(h, k);
mrb_gc_protect(mrb, delKey);
delVal = mrb_hash_delete_key(mrb, hash, delKey);
mrb_gc_protect(mrb, delVal);
@@ -706,8 +706,8 @@ mrb_hash_keys(mrb_state *mrb, mrb_value hash)
p = RARRAY_PTR(ary);
for (k = kh_begin(h); k != kh_end(h); k++) {
if (kh_exist(h, k)) {
- mrb_value kv = kh_key(h,k);
- mrb_hash_value hv = kh_value(h,k);
+ mrb_value kv = kh_key(h, k);
+ mrb_hash_value hv = kh_value(h, k);
p[hv.n] = kv;
}
@@ -739,7 +739,7 @@ mrb_hash_values(mrb_state *mrb, mrb_value hash)
ary = mrb_ary_new_capa(mrb, kh_size(h));
for (k = kh_begin(h); k != kh_end(h); k++) {
if (kh_exist(h, k)) {
- mrb_hash_value hv = kh_value(h,k);
+ mrb_hash_value hv = kh_value(h, k);
mrb_ary_set(mrb, ary, hv.n, hv.v);
}
@@ -812,7 +812,7 @@ mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
for (k = kh_begin(h); k != kh_end(h); k++) {
if (!kh_exist(h, k)) continue;
- if (mrb_equal(mrb, kh_value(h,k).v, val)) {
+ if (mrb_equal(mrb, kh_value(h, k).v, val)) {
return mrb_true_value();
}
}
diff --git a/src/kernel.c b/src/kernel.c
index 8686fe6a5..2f52c7bdf 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -470,51 +470,10 @@ static mrb_value
obj_is_instance_of(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
- mrb_bool instance_of_p;
mrb_get_args(mrb, "C", &arg);
- instance_of_p = mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg));
- return mrb_bool_value(instance_of_p);
-}
-
-static void
-valid_iv_name(mrb_state *mrb, mrb_sym iv_name_id, const char* s, mrb_int len)
-{
- if (len < 2 || !(s[0] == '@' && s[1] != '@')) {
- mrb_name_error(mrb, iv_name_id, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name_id));
- }
-}
-
-static void
-check_iv_name(mrb_state *mrb, mrb_sym iv_name_id)
-{
- const char *s;
- mrb_int len;
-
- s = mrb_sym2name_len(mrb, iv_name_id, &len);
- valid_iv_name(mrb, iv_name_id, s, len);
-}
-
-static mrb_sym
-get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name)
-{
- mrb_sym iv_name_id;
-
- mrb_assert(mrb_symbol_p(iv_name) || mrb_string_p(iv_name));
-
- if (mrb_string_p(iv_name)) {
- char *p = RSTRING_PTR(iv_name);
- mrb_int l = RSTRING_LEN(iv_name);
- iv_name_id = mrb_intern(mrb, p, l);
- valid_iv_name(mrb, iv_name_id, p, l);
- }
- else {
- iv_name_id = mrb_symbol(iv_name);
- check_iv_name(mrb, iv_name_id);
- }
-
- return iv_name_id;
+ return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg)));
}
/* 15.3.1.3.20 */
@@ -538,15 +497,11 @@ get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name)
static mrb_value
mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
{
- mrb_sym mid;
- mrb_value sym;
- mrb_bool defined_p;
-
- mrb_get_args(mrb, "o", &sym);
- mid = get_valid_iv_sym(mrb, sym);
- defined_p = mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid);
+ mrb_sym sym;
- return mrb_bool_value(defined_p);
+ mrb_get_args(mrb, "n", &sym);
+ mrb_iv_check(mrb, sym);
+ return mrb_bool_value(mrb_iv_defined(mrb, self, sym));
}
/* 15.3.1.3.21 */
@@ -572,13 +527,11 @@ mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
{
- mrb_sym iv_name_id;
- mrb_value iv_name;
+ mrb_sym iv_name;
- mrb_get_args(mrb, "o", &iv_name);
-
- iv_name_id = get_valid_iv_sym(mrb, iv_name);
- return mrb_iv_get(mrb, self, iv_name_id);
+ mrb_get_args(mrb, "n", &iv_name);
+ mrb_iv_check(mrb, iv_name);
+ return mrb_iv_get(mrb, self, iv_name);
}
/* 15.3.1.3.22 */
@@ -604,13 +557,12 @@ mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
{
- mrb_sym iv_name_id;
- mrb_value iv_name, val;
-
- mrb_get_args(mrb, "oo", &iv_name, &val);
+ mrb_sym iv_name;
+ mrb_value val;
- iv_name_id = get_valid_iv_sym(mrb, iv_name);
- mrb_iv_set(mrb, self, iv_name_id, val);
+ mrb_get_args(mrb, "no", &iv_name, &val);
+ mrb_iv_check(mrb, iv_name);
+ mrb_iv_set(mrb, self, iv_name, val);
return val;
}
@@ -645,12 +597,10 @@ static mrb_value
mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
- mrb_bool kind_of_p;
mrb_get_args(mrb, "C", &arg);
- kind_of_p = mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg));
- return mrb_bool_value(kind_of_p);
+ return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg)));
}
KHASH_DECLARE(st, mrb_sym, char, FALSE)
@@ -665,7 +615,7 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
if (!h) return;
for (i=0;i<kh_end(h);i++) {
if (kh_exist(h, i)) {
- kh_put(st, mrb, set, kh_key(h,i));
+ kh_put(st, mrb, set, kh_key(h, i));
}
}
}
@@ -694,7 +644,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl
ary = mrb_ary_new(mrb);
for (i=0;i<kh_end(set);i++) {
if (kh_exist(set, i)) {
- mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set,i)));
+ mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
}
}
kh_destroy(st, mrb, set);
@@ -726,7 +676,7 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
ary = mrb_ary_new(mrb);
for (i=0;i<kh_end(set);i++) {
if (kh_exist(set, i)) {
- mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set,i)));
+ mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
}
}
kh_destroy(st, mrb, set);
@@ -911,7 +861,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
mrb_value val;
mrb_get_args(mrb, "n", &sym);
- check_iv_name(mrb, sym);
+ mrb_iv_check(mrb, sym);
val = mrb_iv_remove(mrb, self, sym);
if (mrb_undef_p(val)) {
mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym));
diff --git a/src/load.c b/src/load.c
index 9e8325022..30b466f6b 100644
--- a/src/load.c
+++ b/src/load.c
@@ -14,6 +14,11 @@
#include "mruby/debug.h"
#include "mruby/error.h"
+#define FLAG_BYTEORDER_NATIVE 2
+#define FLAG_BYTEORDER_NONATIVE 0
+#define FLAG_SRC_MALLOC 1
+#define FLAG_SRC_STATIC 0
+
#if !defined(_WIN32) && SIZE_MAX < UINT32_MAX
# define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y))
# define SIZE_ERROR(x) ((x) > SIZE_MAX)
@@ -34,7 +39,7 @@ offset_crc_body(void)
}
static mrb_irep*
-read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc)
+read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
{
size_t i;
const uint8_t *src = bin;
@@ -67,10 +72,18 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) {
return NULL;
}
- irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
- for (i = 0; i < irep->ilen; i++) {
- irep->iseq[i] = (size_t)bin_to_uint32(src); /* iseq */
- src += sizeof(uint32_t);
+ if (!(flags & FLAG_SRC_MALLOC) &&
+ (flags & FLAG_BYTEORDER_NATIVE)) {
+ irep->iseq = (mrb_code*)src;
+ src += sizeof(uint32_t) * irep->ilen;
+ irep->flags |= MRB_ISEQ_NO_FREE;
+ }
+ else {
+ irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
+ for (i = 0; i < irep->ilen; i++) {
+ irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */
+ src += sizeof(uint32_t);
+ }
}
}
@@ -89,7 +102,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
tt = *src++; /* pool TT */
pool_data_len = bin_to_uint16(src); /* pool data length */
src += sizeof(uint16_t);
- if (alloc) {
+ if (flags & FLAG_SRC_MALLOC) {
s = mrb_str_new(mrb, (char *)src, pool_data_len);
}
else {
@@ -137,7 +150,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
continue;
}
- if (alloc) {
+ if (flags & FLAG_SRC_MALLOC) {
irep->syms[i] = mrb_intern(mrb, (char *)src, snl);
}
else {
@@ -159,9 +172,9 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
}
static mrb_irep*
-read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc)
+read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
{
- mrb_irep *irep = read_irep_record_1(mrb, bin, len, alloc);
+ mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags);
size_t i;
if (irep == NULL) {
@@ -172,7 +185,7 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc
for (i=0; i<irep->rlen; i++) {
size_t rlen;
- irep->reps[i] = read_irep_record(mrb, bin, &rlen, alloc);
+ irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags);
if (irep->reps[i] == NULL) {
return NULL;
}
@@ -183,12 +196,12 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc
}
static mrb_irep*
-read_section_irep(mrb_state *mrb, const uint8_t *bin, mrb_bool alloc)
+read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
{
size_t len;
bin += sizeof(struct rite_section_irep_header);
- return read_irep_record(mrb, bin, &len, alloc);
+ return read_irep_record(mrb, bin, &len, flags);
}
static int
@@ -357,7 +370,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
}
static int
-read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc)
+read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
{
const uint8_t *bin;
ptrdiff_t diff;
@@ -378,7 +391,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo
for (i = 0; i < filenames_len; ++i) {
uint16_t f_len = bin_to_uint16(bin);
bin += sizeof(uint16_t);
- if (alloc) {
+ if (flags & FLAG_SRC_MALLOC) {
filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len);
}
else {
@@ -446,7 +459,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec
}
static int
-read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc)
+read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
{
const uint8_t *bin;
ptrdiff_t diff;
@@ -456,7 +469,8 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool a
int result;
uint32_t syms_len;
mrb_sym *syms;
- mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = alloc? mrb_intern : mrb_intern_static;
+ mrb_sym (*intern_func)(mrb_state*, const char*, size_t) =
+ (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static;
bin = start;
header = (struct rite_section_lv_header const*)bin;
@@ -489,12 +503,27 @@ lv_exit:
}
static int
-read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc)
+read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, mrb_bool *byteorder)
{
const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
+ if (byteorder) *byteorder = FALSE;
if (memcmp(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)) != 0) {
- return MRB_DUMP_INVALID_FILE_HEADER;
+ if (byteorder) {
+ uint32_t ident = 0;
+ size_t i;
+
+ for(i=0; i<sizeof(ident); i++) {
+ ident<<=8;
+ ident|=RITE_BINARY_IDENTIFIER[i];
+ }
+ if (memcmp(header->binary_identify, &ident, sizeof(header->binary_identify)) == 0) {
+ *byteorder = TRUE;
+ }
+ else {
+ return MRB_DUMP_INVALID_FILE_HEADER;
+ }
+ }
}
if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) {
@@ -518,15 +547,20 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
uint16_t crc;
size_t bin_size = 0;
size_t n;
+ mrb_bool byteorder;
+ uint8_t flags = FLAG_SRC_STATIC;
if ((mrb == NULL) || (bin == NULL)) {
return NULL;
}
- result = read_binary_header(bin, &bin_size, &crc);
+ result = read_binary_header(bin, &bin_size, &crc, &byteorder);
if (result != MRB_DUMP_OK) {
return NULL;
}
+ if (byteorder) {
+ flags |= FLAG_BYTEORDER_NATIVE;
+ }
n = offset_crc_body();
if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) {
@@ -537,7 +571,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
do {
section_header = (const struct rite_section_header *)bin;
if (memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
- irep = read_section_irep(mrb, bin, FALSE);
+ irep = read_section_irep(mrb, bin, flags);
if (!irep) return NULL;
}
else if (memcmp(section_header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
@@ -549,14 +583,14 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
}
else if (memcmp(section_header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
if (!irep) return NULL; /* corrupted data */
- result = read_section_debug(mrb, bin, irep, FALSE);
+ result = read_section_debug(mrb, bin, irep, flags);
if (result < MRB_DUMP_OK) {
return NULL;
}
}
else if (memcmp(section_header->section_identify, RITE_SECTION_LV_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
if (!irep) return NULL;
- result = read_section_lv(mrb, bin, irep, FALSE);
+ result = read_section_lv(mrb, bin, irep, flags);
if (result < MRB_DUMP_OK) {
return NULL;
}
@@ -668,7 +702,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp)
if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) {
return NULL;
}
- irep = read_irep_record_1(mrb, buf, &len, TRUE);
+ irep = read_irep_record_1(mrb, buf, &len, FLAG_SRC_MALLOC);
mrb_free(mrb, ptr);
if (!irep) return NULL;
for (i=0; i<irep->rlen; i++) {
@@ -715,7 +749,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
mrb_free(mrb, buf);
return NULL;
}
- result = read_binary_header(buf, NULL, &crc);
+ result = read_binary_header(buf, NULL, &crc, NULL);
mrb_free(mrb, buf);
if (result != MRB_DUMP_OK) {
return NULL;
@@ -773,7 +807,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
mrb_free(mrb, bin);
return NULL;
}
- result = read_section_debug(mrb, bin, irep, TRUE);
+ result = read_section_debug(mrb, bin, irep, FLAG_SRC_MALLOC);
mrb_free(mrb, bin);
}
if (result < MRB_DUMP_OK) return NULL;
@@ -788,7 +822,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
mrb_free(mrb, bin);
return NULL;
}
- result = read_section_lv(mrb, bin, irep, TRUE);
+ result = read_section_lv(mrb, bin, irep, FLAG_SRC_MALLOC);
mrb_free(mrb, bin);
}
if (result < MRB_DUMP_OK) return NULL;
diff --git a/src/numeric.c b/src/numeric.c
index 5cf85fc7d..da15c92cc 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -75,7 +75,7 @@ num_pow(mrb_state *mrb, mrb_value x)
* result.
*/
-MRB_API mrb_value
+mrb_value
mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
{
return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
diff --git a/src/parse.y b/src/parse.y
index 0c0a9877f..4cab4162a 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -62,6 +62,7 @@ typedef unsigned int stack_type;
#define CMDARG_P() BITSTACK_SET_P(p->cmdarg_stack)
#define SET_LINENO(c,n) ((c)->lineno = (n))
+#define NODE_LINENO(c,n) do {if (n) ((c)->lineno = (n)->lineno);} while (0)
#define sym(x) ((mrb_sym)(intptr_t)(x))
#define nsym(x) ((node*)(intptr_t)(x))
@@ -275,8 +276,9 @@ new_scope(parser_state *p, node *body)
static node*
new_begin(parser_state *p, node *body)
{
- if (body)
+ if (body) {
return list2((node*)NODE_BEGIN, body);
+ }
return cons((node*)NODE_BEGIN, 0);
}
@@ -391,14 +393,20 @@ new_self(parser_state *p)
static node*
new_call(parser_state *p, node *a, mrb_sym b, node *c)
{
- return list4((node*)NODE_CALL, a, nsym(b), c);
+ node *n = list4((node*)NODE_CALL, a, nsym(b), c);
+ NODE_LINENO(n, a);
+ return n;
}
/* (:fcall self mid args) */
static node*
new_fcall(parser_state *p, mrb_sym b, node *c)
{
- return list4((node*)NODE_FCALL, new_self(p), nsym(b), c);
+ node *n = new_self(p);
+ NODE_LINENO(n, c);
+ n = list4((node*)NODE_FCALL, n, nsym(b), c);
+ NODE_LINENO(n, c);
+ return n;
}
/* (:super . c) */
@@ -997,25 +1005,27 @@ heredoc_end(parser_state *p)
const struct vtable *vars;
}
-%token
+%token <num>
keyword_class
keyword_module
keyword_def
- keyword_undef
keyword_begin
+ keyword_if
+ keyword_unless
+ keyword_while
+ keyword_until
+ keyword_for
+
+%token
+ keyword_undef
keyword_rescue
keyword_ensure
keyword_end
- keyword_if
- keyword_unless
keyword_then
keyword_elsif
keyword_else
keyword_case
keyword_when
- keyword_while
- keyword_until
- keyword_for
keyword_break
keyword_next
keyword_redo
@@ -1155,6 +1165,7 @@ program : {
top_compstmt
{
p->tree = new_scope(p, $2);
+ NODE_LINENO(p->tree, $2);
}
;
@@ -1171,6 +1182,7 @@ top_stmts : none
| top_stmt
{
$$ = new_begin(p, $1);
+ NODE_LINENO($$, $1);
}
| top_stmts terms top_stmt
{
@@ -1202,6 +1214,7 @@ bodystmt : compstmt
{
if ($2) {
$$ = new_rescue(p, $1, $2, $3);
+ NODE_LINENO($$, $1);
}
else if ($3) {
yywarn(p, "else without rescue is useless");
@@ -1234,10 +1247,11 @@ stmts : none
| stmt
{
$$ = new_begin(p, $1);
+ NODE_LINENO($$, $1);
}
| stmts terms stmt
{
- $$ = push($1, newline_node($3));
+ $$ = push($1, newline_node($3));
}
| error stmt
{
@@ -1255,7 +1269,7 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
}
| stmt modifier_if expr_value
{
- $$ = new_if(p, cond($3), $1, 0);
+ $$ = new_if(p, cond($3), $1, 0);
}
| stmt modifier_unless expr_value
{
@@ -1887,6 +1901,7 @@ aref_args : none
| args trailer
{
$$ = $1;
+ NODE_LINENO($$, $1);
}
| args ',' assocs trailer
{
@@ -1895,6 +1910,7 @@ aref_args : none
| assocs trailer
{
$$ = cons(new_hash(p, $1), 0);
+ NODE_LINENO($$, $1);
}
;
@@ -1913,36 +1929,44 @@ opt_call_args : none
| args ','
{
$$ = cons($1,0);
+ NODE_LINENO($$, $1);
}
| args ',' assocs ','
{
$$ = cons(push($1, new_hash(p, $3)), 0);
+ NODE_LINENO($$, $1);
}
| assocs ','
{
$$ = cons(list1(new_hash(p, $1)), 0);
+ NODE_LINENO($$, $1);
}
;
call_args : command
{
$$ = cons(list1($1), 0);
+ NODE_LINENO($$, $1);
}
| args opt_block_arg
{
$$ = cons($1, $2);
+ NODE_LINENO($$, $1);
}
| assocs opt_block_arg
{
$$ = cons(list1(new_hash(p, $1)), $2);
+ NODE_LINENO($$, $1);
}
| args ',' assocs opt_block_arg
{
$$ = cons(push($1, new_hash(p, $3)), $4);
+ NODE_LINENO($$, $1);
}
| block_arg
{
$$ = cons(0, $1);
+ NODE_LINENO($$, $1);
}
;
@@ -1976,10 +2000,12 @@ opt_block_arg : ',' block_arg
args : arg_value
{
$$ = cons($1, 0);
+ NODE_LINENO($$, $1);
}
| tSTAR arg_value
{
$$ = cons(new_splat(p, $2), 0);
+ NODE_LINENO($$, $2);
}
| args ',' arg_value
{
@@ -2026,23 +2052,23 @@ primary : literal
}
| keyword_begin
{
- $<stack>1 = p->cmdarg_stack;
+ $<stack>$ = p->cmdarg_stack;
p->cmdarg_stack = 0;
}
bodystmt
keyword_end
{
- p->cmdarg_stack = $<stack>1;
+ p->cmdarg_stack = $<stack>2;
$$ = $3;
}
| tLPAREN_ARG
{
- $<stack>1 = p->cmdarg_stack;
+ $<stack>$ = p->cmdarg_stack;
p->cmdarg_stack = 0;
}
expr {p->lstate = EXPR_ENDARG;} rparen
{
- p->cmdarg_stack = $<stack>1;
+ p->cmdarg_stack = $<stack>2;
$$ = $3;
}
| tLPAREN_ARG {p->lstate = EXPR_ENDARG;} rparen
@@ -2064,10 +2090,12 @@ primary : literal
| tLBRACK aref_args ']'
{
$$ = new_array(p, $2);
+ NODE_LINENO($$, $2);
}
| tLBRACE assoc_list '}'
{
$$ = new_hash(p, $2);
+ NODE_LINENO($$, $2);
}
| keyword_return
{
@@ -2122,6 +2150,7 @@ primary : literal
keyword_end
{
$$ = new_if(p, cond($2), $4, $5);
+ SET_LINENO($$, $1);
}
| keyword_unless expr_value then
compstmt
@@ -2129,18 +2158,21 @@ primary : literal
keyword_end
{
$$ = new_unless(p, cond($2), $4, $5);
+ SET_LINENO($$, $1);
}
| keyword_while {COND_PUSH(1);} expr_value do {COND_POP();}
compstmt
keyword_end
{
$$ = new_while(p, cond($3), $6);
+ SET_LINENO($$, $1);
}
| keyword_until {COND_PUSH(1);} expr_value do {COND_POP();}
compstmt
keyword_end
{
$$ = new_until(p, cond($3), $6);
+ SET_LINENO($$, $1);
}
| keyword_case expr_value opt_terms
case_body
@@ -2160,11 +2192,9 @@ primary : literal
keyword_end
{
$$ = new_for(p, $2, $5, $8);
+ SET_LINENO($$, $1);
}
| keyword_class
- {
- $<num>$ = p->lineno;
- }
cpath superclass
{
if (p->in_def || p->in_single)
@@ -2174,14 +2204,11 @@ primary : literal
bodystmt
keyword_end
{
- $$ = new_class(p, $3, $4, $6);
- SET_LINENO($$, $<num>2);
- local_resume(p, $<nd>5);
+ $$ = new_class(p, $2, $3, $5);
+ SET_LINENO($$, $1);
+ local_resume(p, $<nd>4);
}
| keyword_class
- {
- $<num>$ = p->lineno;
- }
tLSHFT expr
{
$<num>$ = p->in_def;
@@ -2195,16 +2222,13 @@ primary : literal
bodystmt
keyword_end
{
- $$ = new_sclass(p, $4, $8);
- SET_LINENO($$, $<num>2);
- local_resume(p, $<nd>7->car);
- p->in_def = $<num>5;
- p->in_single = (int)(intptr_t)$<nd>7->cdr;
+ $$ = new_sclass(p, $3, $7);
+ SET_LINENO($$, $1);
+ local_resume(p, $<nd>6->car);
+ p->in_def = $<num>4;
+ p->in_single = (int)(intptr_t)$<nd>6->cdr;
}
| keyword_module
- {
- $<num>$ = p->lineno;
- }
cpath
{
if (p->in_def || p->in_single)
@@ -2214,42 +2238,50 @@ primary : literal
bodystmt
keyword_end
{
- $$ = new_module(p, $3, $5);
- SET_LINENO($$, $<num>2);
- local_resume(p, $<nd>4);
+ $$ = new_module(p, $2, $4);
+ SET_LINENO($$, $1);
+ local_resume(p, $<nd>3);
}
| keyword_def fname
{
+ $<stack>$ = p->cmdarg_stack;
+ p->cmdarg_stack = 0;
+ }
+ {
p->in_def++;
$<nd>$ = local_switch(p);
- $<stack>1 = p->cmdarg_stack;
- p->cmdarg_stack = 0;
}
f_arglist
bodystmt
keyword_end
{
- $$ = new_def(p, $2, $4, $5);
- local_resume(p, $<nd>3);
+ $$ = new_def(p, $2, $5, $6);
+ SET_LINENO($$, $1);
+ local_resume(p, $<nd>4);
p->in_def--;
- p->cmdarg_stack = $<stack>1;
+ p->cmdarg_stack = $<stack>3;
}
- | keyword_def singleton dot_or_colon {p->lstate = EXPR_FNAME;} fname
+ | keyword_def singleton dot_or_colon
+ {
+ p->lstate = EXPR_FNAME;
+ $<stack>$ = p->cmdarg_stack;
+ p->cmdarg_stack = 0;
+ }
+ fname
{
p->in_single++;
p->lstate = EXPR_ENDFN; /* force for args */
$<nd>$ = local_switch(p);
- $<stack>1 = p->cmdarg_stack;
- p->cmdarg_stack = 0;
}
f_arglist
bodystmt
keyword_end
{
$$ = new_sdef(p, $2, $5, $7, $8);
+ SET_LINENO($$, $1);
local_resume(p, $<nd>6);
p->in_single--;
- p->cmdarg_stack = $<stack>1;
+ p->cmdarg_stack = $<stack>4;
}
| keyword_break
{
@@ -3163,6 +3195,7 @@ assoc_list : none
assocs : assoc
{
$$ = list1($1);
+ NODE_LINENO($$, $1);
}
| assocs ',' assoc
{
@@ -3934,22 +3967,22 @@ parse_string(parser_state *p)
if (type & STR_FUNC_REGEXP) {
int f = 0;
- int c;
+ int re_opt;
char *s = strndup(tok(p), toklen(p));
char flags[3];
char *flag = flags;
char *dup;
newtok(p);
- while (c = nextc(p), c >= 0 && ISALPHA(c)) {
- switch (c) {
+ while (re_opt = nextc(p), re_opt >= 0 && ISALPHA(re_opt)) {
+ switch (re_opt) {
case 'i': f |= 1; break;
case 'x': f |= 2; break;
case 'm': f |= 4; break;
- default: tokadd(p, c); break;
+ default: tokadd(p, re_opt); break;
}
}
- pushback(p, c);
+ pushback(p, re_opt);
if (toklen(p)) {
char msg[128];
tokfix(p);
@@ -5210,6 +5243,7 @@ parser_yylex(parser_state *p)
kw = mrb_reserved_word(tok(p), toklen(p));
if (kw) {
enum mrb_lex_state_enum state = p->lstate;
+ yylval.num = p->lineno;
p->lstate = kw->state;
if (state == EXPR_FNAME) {
yylval.id = intern_cstr(kw->name);
@@ -5296,6 +5330,7 @@ parser_init_cxt(parser_state *p, mrbc_context *cxt)
}
}
p->capture_errors = cxt->capture_errors;
+ p->no_optimize = cxt->no_optimize;
if (cxt->partial_hook) {
p->cxt = cxt;
}
@@ -5324,7 +5359,7 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt)
void mrb_codedump_all(mrb_state*, struct RProc*);
void mrb_parser_dump(mrb_state *mrb, node *tree, int offset);
-void
+MRB_API void
mrb_parser_parse(parser_state *p, mrbc_context *c)
{
struct mrb_jmpbuf buf;
@@ -5357,7 +5392,7 @@ mrb_parser_parse(parser_state *p, mrbc_context *c)
MRB_END_EXC(p->jmp);
}
-parser_state*
+MRB_API parser_state*
mrb_parser_new(mrb_state *mrb)
{
mrb_pool *pool;
@@ -5399,7 +5434,7 @@ mrb_parser_new(mrb_state *mrb)
return p;
}
-void
+MRB_API void
mrb_parser_free(parser_state *p) {
mrb_pool_close(p->pool);
}
@@ -5440,7 +5475,7 @@ mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser
c->partial_data = data;
}
-void
+MRB_API void
mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
{
mrb_sym sym;
@@ -5468,7 +5503,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
p->filename_table[p->filename_table_length - 1] = sym;
}
-char const*
+MRB_API char const*
mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
if (idx >= p->filename_table_length) { return NULL; }
else {
@@ -5477,7 +5512,7 @@ mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
}
#ifdef ENABLE_STDIO
-parser_state*
+MRB_API parser_state*
mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
{
parser_state *p;
@@ -5492,7 +5527,7 @@ mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
}
#endif
-parser_state*
+MRB_API parser_state*
mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c)
{
parser_state *p;
@@ -5506,7 +5541,7 @@ mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c)
return p;
}
-parser_state*
+MRB_API parser_state*
mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c)
{
return mrb_parse_nstring(mrb, s, strlen(s), c);
@@ -5569,38 +5604,38 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
}
#ifdef ENABLE_STDIO
-mrb_value
+MRB_API mrb_value
mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
{
return load_exec(mrb, mrb_parse_file(mrb, f, c), c);
}
-mrb_value
+MRB_API mrb_value
mrb_load_file(mrb_state *mrb, FILE *f)
{
return mrb_load_file_cxt(mrb, f, NULL);
}
#endif
-mrb_value
+MRB_API mrb_value
mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c)
{
return load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
}
-mrb_value
+MRB_API mrb_value
mrb_load_nstring(mrb_state *mrb, const char *s, int len)
{
return mrb_load_nstring_cxt(mrb, s, len, NULL);
}
-mrb_value
+MRB_API mrb_value
mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c)
{
return mrb_load_nstring_cxt(mrb, s, strlen(s), c);
}
-mrb_value
+MRB_API mrb_value
mrb_load_string(mrb_state *mrb, const char *s)
{
return mrb_load_string_cxt(mrb, s, NULL);
@@ -5609,8 +5644,9 @@ mrb_load_string(mrb_state *mrb, const char *s)
#ifdef ENABLE_STDIO
static void
-dump_prefix(int offset)
+dump_prefix(node *tree, int offset)
{
+ printf("%05d ", tree->lineno);
while (offset--) {
putc(' ', stdout);
putc(' ', stdout);
@@ -5632,14 +5668,14 @@ void
mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
{
#ifdef ENABLE_STDIO
- int n;
+ int nodetype;
if (!tree) return;
again:
- dump_prefix(offset);
- n = (int)(intptr_t)tree->car;
+ dump_prefix(tree, offset);
+ nodetype = (int)(intptr_t)tree->car;
tree = tree->cdr;
- switch (n) {
+ switch (nodetype) {
case NODE_BEGIN:
printf("NODE_BEGIN:\n");
dump_recur(mrb, tree, offset+1);
@@ -5648,7 +5684,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_RESCUE:
printf("NODE_RESCUE:\n");
if (tree->car) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
}
@@ -5656,22 +5692,22 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
if (tree->car) {
node *n2 = tree->car;
- dump_prefix(offset+1);
+ dump_prefix(n2, offset+1);
printf("rescue:\n");
while (n2) {
node *n3 = n2->car;
if (n3->car) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("handle classes:\n");
dump_recur(mrb, n3->car, offset+3);
}
if (n3->cdr->car) {
- dump_prefix(offset+2);
+ dump_prefix(n3, offset+2);
printf("exc_var:\n");
mrb_parser_dump(mrb, n3->cdr->car, offset+3);
}
if (n3->cdr->cdr->car) {
- dump_prefix(offset+2);
+ dump_prefix(n3, offset+2);
printf("rescue body:\n");
mrb_parser_dump(mrb, n3->cdr->cdr->car, offset+3);
}
@@ -5680,7 +5716,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
}
tree = tree->cdr;
if (tree->car) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("else:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
}
@@ -5688,10 +5724,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_ENSURE:
printf("NODE_ENSURE:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("ensure:\n");
mrb_parser_dump(mrb, tree->cdr->cdr, offset+2);
break;
@@ -5703,62 +5739,62 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_BLOCK:
block:
printf("NODE_BLOCK:\n");
- tree = tree->cdr;
- if (tree->car) {
- node *n = tree->car;
+ tree = tree->cdr;
+ if (tree->car) {
+ node *n = tree->car;
- if (n->car) {
- dump_prefix(offset+1);
- printf("mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
- }
- n = n->cdr;
- if (n->car) {
- dump_prefix(offset+1);
- printf("optional args:\n");
- {
- node *n2 = n->car;
+ if (n->car) {
+ dump_prefix(n, offset+1);
+ printf("mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
+ }
+ n = n->cdr;
+ if (n->car) {
+ dump_prefix(n, offset+1);
+ printf("optional args:\n");
+ {
+ node *n2 = n->car;
- while (n2) {
- dump_prefix(offset+2);
- printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
- mrb_parser_dump(mrb, n2->car->cdr, 0);
- n2 = n2->cdr;
+ while (n2) {
+ dump_prefix(n2, offset+2);
+ printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+ mrb_parser_dump(mrb, n2->car->cdr, 0);
+ n2 = n2->cdr;
+ }
}
}
+ n = n->cdr;
+ if (n->car) {
+ dump_prefix(n, offset+1);
+ printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ }
+ n = n->cdr;
+ if (n->car) {
+ dump_prefix(n, offset+1);
+ printf("post mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
+ }
+ n = n->cdr;
+ if (n) {
+ dump_prefix(n, offset+1);
+ printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+ }
}
- n = n->cdr;
- if (n->car) {
- dump_prefix(offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
- }
- n = n->cdr;
- if (n->car) {
- dump_prefix(offset+1);
- printf("post mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
- }
- n = n->cdr;
- if (n) {
- dump_prefix(offset+1);
- printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
- }
- }
- dump_prefix(offset+1);
- printf("body:\n");
- mrb_parser_dump(mrb, tree->cdr->car, offset+2);
- break;
+ dump_prefix(tree, offset+1);
+ printf("body:\n");
+ mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+ break;
case NODE_IF:
printf("NODE_IF:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("cond:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("then:\n");
mrb_parser_dump(mrb, tree->cdr->car, offset+2);
if (tree->cdr->cdr->car) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("else:\n");
mrb_parser_dump(mrb, tree->cdr->cdr->car, offset+2);
}
@@ -5783,10 +5819,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
}
tree = tree->cdr;
while (tree) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("case:\n");
dump_recur(mrb, tree->car->car, offset+2);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->car->cdr, offset+2);
tree = tree->cdr;
@@ -5795,47 +5831,47 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_WHILE:
printf("NODE_WHILE:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("cond:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->cdr, offset+2);
break;
case NODE_UNTIL:
printf("NODE_UNTIL:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("cond:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->cdr, offset+2);
break;
case NODE_FOR:
printf("NODE_FOR:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("var:\n");
{
node *n2 = tree->car;
if (n2->car) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("pre:\n");
dump_recur(mrb, n2->car, offset+3);
}
n2 = n2->cdr;
if (n2) {
if (n2->car) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("rest:\n");
mrb_parser_dump(mrb, n2->car, offset+3);
}
n2 = n2->cdr;
if (n2) {
if (n2->car) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("post:\n");
dump_recur(mrb, n2->car, offset+3);
}
@@ -5843,11 +5879,11 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
}
}
tree = tree->cdr;
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("in:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
tree = tree->cdr;
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("do:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
break;
@@ -5859,9 +5895,9 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
mrb_bool first_lval = TRUE;
if (n2 && (n2->car || n2->cdr)) {
- dump_prefix(offset+1);
+ dump_prefix(n2, offset+1);
printf("local variables:\n");
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
while (n2) {
if (n2->car) {
if (!first_lval) printf(", ");
@@ -5881,17 +5917,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_CALL:
printf("NODE_CALL:\n");
mrb_parser_dump(mrb, tree->car, offset+1);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("method='%s' (%d)\n",
mrb_sym2name(mrb, sym(tree->cdr->car)),
(int)(intptr_t)tree->cdr->car);
tree = tree->cdr->cdr->car;
if (tree) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("args:\n");
dump_recur(mrb, tree->car, offset+2);
if (tree->cdr) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("block:\n");
mrb_parser_dump(mrb, tree->cdr, offset+2);
}
@@ -5913,13 +5949,13 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_COLON2:
printf("NODE_COLON2:\n");
mrb_parser_dump(mrb, tree->car, offset+1);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr)));
break;
case NODE_COLON3:
printf("NODE_COLON3:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("::%s\n", mrb_sym2name(mrb, sym(tree)));
break;
@@ -5931,10 +5967,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_HASH:
printf("NODE_HASH:\n");
while (tree) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("key:\n");
mrb_parser_dump(mrb, tree->car->car, offset+2);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("value:\n");
mrb_parser_dump(mrb, tree->car->cdr, offset+2);
tree = tree->cdr;
@@ -5948,33 +5984,33 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_ASGN:
printf("NODE_ASGN:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("lhs:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("rhs:\n");
mrb_parser_dump(mrb, tree->cdr, offset+2);
break;
case NODE_MASGN:
printf("NODE_MASGN:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("mlhs:\n");
{
node *n2 = tree->car;
if (n2->car) {
- dump_prefix(offset+2);
+ dump_prefix(tree, offset+2);
printf("pre:\n");
dump_recur(mrb, n2->car, offset+3);
}
n2 = n2->cdr;
if (n2) {
if (n2->car) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("rest:\n");
if (n2->car == (node*)-1) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("(empty)\n");
}
else {
@@ -5984,25 +6020,25 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
n2 = n2->cdr;
if (n2) {
if (n2->car) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("post:\n");
dump_recur(mrb, n2->car, offset+3);
}
}
}
}
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("rhs:\n");
mrb_parser_dump(mrb, tree->cdr, offset+2);
break;
case NODE_OP_ASGN:
printf("NODE_OP_ASGN:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("lhs:\n");
mrb_parser_dump(mrb, tree->car, offset+2);
tree = tree->cdr;
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), (int)(intptr_t)tree->car);
tree = tree->cdr;
mrb_parser_dump(mrb, tree->car, offset+1);
@@ -6011,11 +6047,11 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_SUPER:
printf("NODE_SUPER:\n");
if (tree) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("args:\n");
dump_recur(mrb, tree->car, offset+2);
if (tree->cdr) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("block:\n");
mrb_parser_dump(mrb, tree->cdr, offset+2);
}
@@ -6076,10 +6112,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_MATCH:
printf("NODE_MATCH:\n");
- dump_prefix(offset + 1);
+ dump_prefix(tree, offset + 1);
printf("lhs:\n");
mrb_parser_dump(mrb, tree->car, offset + 2);
- dump_prefix(offset + 1);
+ dump_prefix(tree, offset + 1);
printf("rhs:\n");
mrb_parser_dump(mrb, tree->cdr, offset + 2);
break;
@@ -6139,9 +6175,9 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_DREGX:
printf("NODE_DREGX\n");
dump_recur(mrb, tree->car, offset+1);
- dump_prefix(offset);
+ dump_prefix(tree, offset);
printf("tail: %s\n", (char*)tree->cdr->cdr->car);
- dump_prefix(offset);
+ dump_prefix(tree, offset);
printf("opt: %s\n", (char*)tree->cdr->cdr->cdr);
break;
@@ -6186,24 +6222,24 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_CLASS:
printf("NODE_CLASS:\n");
if (tree->car->car == (node*)0) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
}
else if (tree->car->car == (node*)1) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
}
else {
mrb_parser_dump(mrb, tree->car->car, offset+1);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
}
if (tree->cdr->car) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("super:\n");
mrb_parser_dump(mrb, tree->cdr->car, offset+2);
}
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->cdr->cdr->car->cdr, offset+2);
break;
@@ -6211,19 +6247,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_MODULE:
printf("NODE_MODULE:\n");
if (tree->car->car == (node*)0) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
}
else if (tree->car->car == (node*)1) {
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
}
else {
mrb_parser_dump(mrb, tree->car->car, offset+1);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
}
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
break;
@@ -6231,14 +6267,14 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_SCLASS:
printf("NODE_SCLASS:\n");
mrb_parser_dump(mrb, tree->car, offset+1);
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("body:\n");
mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
break;
case NODE_DEF:
printf("NODE_DEF:\n");
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf("%s\n", mrb_sym2name(mrb, sym(tree->car)));
tree = tree->cdr;
{
@@ -6246,9 +6282,9 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
mrb_bool first_lval = TRUE;
if (n2 && (n2->car || n2->cdr)) {
- dump_prefix(offset+1);
+ dump_prefix(n2, offset+1);
printf("local variables:\n");
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
while (n2) {
if (n2->car) {
if (!first_lval) printf(", ");
@@ -6265,19 +6301,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("mandatory args:\n");
dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("optional args:\n");
{
node *n2 = n->car;
while (n2) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
mrb_parser_dump(mrb, n2->car->cdr, 0);
n2 = n2->cdr;
@@ -6286,18 +6322,18 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("post mandatory args:\n");
dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
@@ -6308,26 +6344,26 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
printf("NODE_SDEF:\n");
mrb_parser_dump(mrb, tree->car, offset+1);
tree = tree->cdr;
- dump_prefix(offset+1);
+ dump_prefix(tree, offset+1);
printf(":%s\n", mrb_sym2name(mrb, sym(tree->car)));
tree = tree->cdr->cdr;
if (tree->car) {
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("mandatory args:\n");
dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("optional args:\n");
{
node *n2 = n->car;
while (n2) {
- dump_prefix(offset+2);
+ dump_prefix(n2, offset+2);
printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
mrb_parser_dump(mrb, n2->car->cdr, 0);
n2 = n2->cdr;
@@ -6336,18 +6372,18 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("post mandatory args:\n");
dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
+ dump_prefix(n, offset+1);
printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
@@ -6366,7 +6402,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
default:
- printf("node type: %d (0x%x)\n", n, (unsigned)n);
+ printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype);
break;
}
#endif
diff --git a/src/pool.c b/src/pool.c
index ffddd2552..60670ad4a 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -47,7 +47,7 @@ struct mrb_pool {
# define ALIGN_PADDING(x) (0)
#endif
-mrb_pool*
+MRB_API mrb_pool*
mrb_pool_open(mrb_state *mrb)
{
mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool));
@@ -60,7 +60,7 @@ mrb_pool_open(mrb_state *mrb)
return pool;
}
-void
+MRB_API void
mrb_pool_close(mrb_pool *pool)
{
struct mrb_pool_page *page, *tmp;
@@ -91,7 +91,7 @@ page_alloc(mrb_pool *pool, size_t len)
return page;
}
-void*
+MRB_API void*
mrb_pool_alloc(mrb_pool *pool, size_t len)
{
struct mrb_pool_page *page;
@@ -119,7 +119,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len)
return page->last;
}
-mrb_bool
+MRB_API mrb_bool
mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len)
{
struct mrb_pool_page *page;
@@ -140,7 +140,7 @@ mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len)
return FALSE;
}
-void*
+MRB_API void*
mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen)
{
struct mrb_pool_page *page;
diff --git a/src/proc.c b/src/proc.c
index 0b776ea80..ebdafccf8 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -34,17 +34,27 @@ mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
return p;
}
-static inline void
+static struct REnv*
+env_new(mrb_state *mrb, int nlocals)
+{
+ struct REnv *e;
+
+ e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env);
+ MRB_ENV_STACK_LEN(e) = (unsigned int)nlocals;
+ e->mid = mrb->c->ci->mid;
+ e->cioff = mrb->c->ci - mrb->c->cibase;
+ e->stack = mrb->c->stack;
+
+ return e;
+}
+
+static void
closure_setup(mrb_state *mrb, struct RProc *p, int nlocals)
{
struct REnv *e;
if (!mrb->c->ci->env) {
- e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env);
- MRB_ENV_STACK_LEN(e) = (unsigned int)nlocals+1; /* add space for receiver */
- e->mid = mrb->c->ci->mid;
- e->cioff = mrb->c->ci - mrb->c->cibase;
- e->stack = mrb->c->stack;
+ e = env_new(mrb, nlocals);
mrb->c->ci->env = e;
}
else {
@@ -62,7 +72,7 @@ mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
return p;
}
-struct RProc *
+MRB_API struct RProc *
mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
{
struct RProc *p;
@@ -76,15 +86,55 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
}
MRB_API struct RProc *
-mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals)
+mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv)
{
struct RProc *p = mrb_proc_new_cfunc(mrb, func);
-
- closure_setup(mrb, p, nlocals);
+ struct REnv *e;
+ int i;
+
+ p->env = e = env_new(mrb, argc);
+ MRB_ENV_UNSHARE_STACK(e);
+ e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
+ if (argv) {
+ for (i = 0; i < argc; ++i) {
+ e->stack[i] = argv[i];
+ }
+ }
+ else {
+ for (i = 0; i < argc; ++i) {
+ SET_NIL_VALUE(e->stack[i]);
+ }
+ }
return p;
}
-void
+MRB_API struct RProc *
+mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals)
+{
+ return mrb_proc_new_cfunc_with_env(mrb, func, nlocals, NULL);
+}
+
+MRB_API mrb_value
+mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx)
+{
+ struct RProc *p = mrb->c->ci->proc;
+ struct REnv *e = p->env;
+
+ if (!MRB_PROC_CFUNC_P(p)) {
+ mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc.");
+ }
+ if (!e) {
+ mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv.");
+ }
+ if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) {
+ mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)",
+ mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));
+ }
+
+ return e->stack[idx];
+}
+
+MRB_API void
mrb_proc_copy(struct RProc *a, struct RProc *b)
{
a->flags = b->flags;
diff --git a/src/state.c b/src/state.c
index 8d6993b6f..2efd34334 100644
--- a/src/state.c
+++ b/src/state.c
@@ -256,7 +256,7 @@ mrb_close(mrb_state *mrb)
mrb_free(mrb, mrb);
}
-mrb_irep*
+MRB_API mrb_irep*
mrb_add_irep(mrb_state *mrb)
{
static const mrb_irep mrb_irep_zero = { 0 };
diff --git a/src/string.c b/src/string.c
index e8632e5e4..56827922b 100644
--- a/src/string.c
+++ b/src/string.c
@@ -148,7 +148,7 @@ str_new(mrb_state *mrb, const char *p, size_t len)
s = mrb_obj_alloc_string(mrb);
if (len < RSTRING_EMBED_LEN_MAX) {
RSTR_SET_EMBED_FLAG(s);
- RSTR_SET_EMBED_LEN(s,len);
+ RSTR_SET_EMBED_LEN(s, len);
if (p) {
memcpy(s->as.ary, p, len);
}
@@ -393,7 +393,7 @@ mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other)
*
* Returns a new string object containing a copy of <i>str</i>.
*/
-mrb_value
+MRB_API mrb_value
mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b)
{
struct RString *s = mrb_str_ptr(a);
@@ -615,7 +615,7 @@ mrb_str_equal_m(mrb_state *mrb, mrb_value str1)
return mrb_bool_value(mrb_str_equal(mrb, str1, str2));
}
/* ---------------------------------- */
-mrb_value
+MRB_API mrb_value
mrb_str_to_str(mrb_state *mrb, mrb_value str)
{
mrb_value s;
@@ -637,18 +637,17 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr)
return RSTRING_PTR(str);
}
-static mrb_value
-noregexp(mrb_state *mrb, mrb_value self)
+void
+mrb_noregexp(mrb_state *mrb, mrb_value self)
{
mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented");
- return mrb_nil_value();
}
-static void
-regexp_check(mrb_state *mrb, mrb_value obj)
+void
+mrb_regexp_check(mrb_state *mrb, mrb_value obj)
{
if (mrb_regexp_p(mrb, obj)) {
- noregexp(mrb, obj);
+ mrb_noregexp(mrb, obj);
}
}
@@ -738,7 +737,7 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
{
mrb_int idx;
- regexp_check(mrb, indx);
+ mrb_regexp_check(mrb, indx);
switch (mrb_type(indx)) {
case MRB_TT_FIXNUM:
idx = mrb_fixnum(indx);
@@ -820,7 +819,7 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str)
argc = mrb_get_args(mrb, "o|o", &a1, &a2);
if (argc == 2) {
- regexp_check(mrb, a1);
+ mrb_regexp_check(mrb, a1);
return mrb_str_substr(mrb, str, mrb_fixnum(a1), mrb_fixnum(a2));
}
if (argc != 1) {
@@ -1159,7 +1158,7 @@ mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
return mrb_obj_value(s);
}
-mrb_value
+MRB_API mrb_value
mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
{
if (len < 0) return mrb_nil_value();
@@ -1284,7 +1283,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
else
sub = mrb_nil_value();
}
- regexp_check(mrb, sub);
+ mrb_regexp_check(mrb, sub);
if (pos < 0) {
pos += RSTRING_LEN(str);
if (pos < 0) {
@@ -1623,7 +1622,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
if (pos < 0) {
pos += len;
if (pos < 0) {
- regexp_check(mrb, sub);
+ mrb_regexp_check(mrb, sub);
return mrb_nil_value();
}
}
@@ -1636,12 +1635,11 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
else
sub = mrb_nil_value();
}
- regexp_check(mrb, sub);
+ mrb_regexp_check(mrb, sub);
switch (mrb_type(sub)) {
case MRB_TT_FIXNUM: {
int c = mrb_fixnum(sub);
- mrb_int len = RSTRING_LEN(str);
unsigned char *p = (unsigned char*)RSTRING_PTR(str);
for (pos=len-1;pos>=0;pos--) {
@@ -1746,7 +1744,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
}
}
else {
- noregexp(mrb, str);
+ mrb_noregexp(mrb, str);
}
}
@@ -1815,7 +1813,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
beg = ptr - temp;
}
else {
- noregexp(mrb, str);
+ mrb_noregexp(mrb, str);
}
if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
if (RSTRING_LEN(str) == beg) {
@@ -2060,9 +2058,6 @@ mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck)
double d;
enum {max_width = 20};
-#define OutOfRange() (((w = end - p) > max_width) ? \
- (w = max_width, ellipsis = "...") : \
- (w = (int)(end - p), ellipsis = ""))
if (!p) return 0.0;
while (ISSPACE(*p)) p++;
diff --git a/src/symbol.c b/src/symbol.c
index 5e40fa315..7fcef2817 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -10,6 +10,7 @@
#include "mruby.h"
#include "mruby/khash.h"
#include "mruby/string.h"
+#include "mruby/dump.h"
/* ------------------------------------------------------ */
typedef struct symbol_name {
@@ -36,7 +37,15 @@ KHASH_DECLARE(n2s, symbol_name, mrb_sym, TRUE)
KHASH_DEFINE (n2s, symbol_name, mrb_sym, TRUE, sym_hash_func, sym_hash_equal)
/* ------------------------------------------------------ */
-#define MRB_SYM_MAX SHRT_MAX
+static void
+sym_validate_len(mrb_state *mrb, size_t len)
+{
+ if (len >= RITE_LV_NULL_MARK) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long");
+ }
+}
+
+#define MRB_SYM_MAX UINT16_MAX
static mrb_value
sym_tbl_overflow_new_str(mrb_state *mrb, const char *name, size_t len)
@@ -53,9 +62,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
mrb_sym sym;
char *p;
- if (len > (UINT16_MAX-1)) { /* UINT16_MAX is reverved */
- mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long");
- }
+ sym_validate_len(mrb, len);
sname.lit = lit;
sname.len = (uint16_t)len;
sname.name = name;
@@ -123,9 +130,7 @@ mrb_check_intern(mrb_state *mrb, const char *name, size_t len)
symbol_name sname = { 0 };
khiter_t k;
- if (len > UINT16_MAX) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long");
- }
+ sym_validate_len(mrb, len);
sname.len = (uint16_t)len;
sname.name = name;
diff --git a/src/variable.c b/src/variable.c
index a50256353..440a33948 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -542,6 +542,32 @@ mrb_iv_defined(mrb_state *mrb, mrb_value obj, mrb_sym sym)
return mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), sym);
}
+#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
+
+MRB_API mrb_bool
+mrb_iv_p(mrb_state *mrb, mrb_sym iv_name)
+{
+ const char *s;
+ mrb_int i, len;
+
+ s = mrb_sym2name_len(mrb, iv_name, &len);
+ if (len < 2) return FALSE;
+ if (s[0] != '@') return FALSE;
+ if (s[1] == '@') return FALSE;
+ for (i=1; i<len; i++) {
+ if (!identchar(s[i])) return FALSE;
+ }
+ return TRUE;
+}
+
+MRB_API void
+mrb_iv_check(mrb_state *mrb, mrb_sym iv_name)
+{
+ if (!mrb_iv_p(mrb, iv_name)) {
+ mrb_name_error(mrb, iv_name, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name));
+ }
+}
+
MRB_API void
mrb_iv_copy(mrb_state *mrb, mrb_value dest, mrb_value src)
{
@@ -809,7 +835,7 @@ mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym)
return mrb_mod_cv_defined(mrb, mrb_class_ptr(mod), sym);
}
-MRB_API mrb_value
+mrb_value
mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
{
struct RClass *c = mrb->c->ci->proc->target_class;
@@ -819,7 +845,7 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
return mrb_mod_cv_get(mrb, c, sym);
}
-MRB_API void
+void
mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
{
struct RClass *c = mrb->c->ci->proc->target_class;
@@ -1093,7 +1119,7 @@ mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id)
return mrb_const_defined_0(mrb, klass, id, TRUE, FALSE);
}
-mrb_value
+MRB_API mrb_value
mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id)
{
return mrb_iv_get(mrb, obj, id);
diff --git a/src/vm.c b/src/vm.c
index 236d33a12..78fb0c31f 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -227,7 +227,6 @@ cipush(mrb_state *mrb)
c->ciend = c->cibase + size * 2;
}
ci = ++c->ci;
- ci->nregs = 2; /* protect method_missing arg and block */
ci->eidx = eidx;
ci->ridx = ridx;
ci->env = 0;
@@ -253,6 +252,7 @@ cipop(mrb_state *mrb)
stack_copy(p, e->stack, len);
}
e->stack = p;
+ mrb_write_barrier(mrb, (struct RBasic *)e);
}
c->ci--;
@@ -467,6 +467,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
ci->nregs = p->body.irep->nregs;
ci = cipush(mrb);
+ ci->nregs = 0;
ci->target_class = 0;
ci->pc = p->body.irep->iseq;
ci->stackent = mrb->c->stack;
@@ -496,6 +497,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
}
ci->nregs = p->body.irep->nregs;
ci = cipush(mrb);
+ ci->nregs = 0;
ci->target_class = 0;
ci->pc = p->body.irep->iseq;
ci->stackent = mrb->c->stack;
@@ -1248,6 +1250,7 @@ RETRY_TRY_BLOCK:
mrb->c->stack[0] = recv;
if (MRB_PROC_CFUNC_P(m)) {
+ ci->nregs = 0;
mrb->c->stack[0] = m->body.func(mrb, recv);
mrb_gc_arena_restore(mrb, ai);
if (mrb->exc) goto L_RAISE;
@@ -2110,7 +2113,7 @@ RETRY_TRY_BLOCK:
else {
struct RArray *ary = mrb_ary_ptr(v);
int len = ary->len;
- int i;
+ int idx;
if (len > pre + post) {
regs[a++] = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
@@ -2120,11 +2123,11 @@ RETRY_TRY_BLOCK:
}
else {
regs[a++] = mrb_ary_new_capa(mrb, 0);
- for (i=0; i+pre<len; i++) {
- regs[a+i] = ary->ptr[pre+i];
+ for (idx=0; idx+pre<len; i++) {
+ regs[a+i] = ary->ptr[pre+idx];
}
- while (i < post) {
- SET_NIL_VALUE(regs[a+i]);
+ while (idx < post) {
+ SET_NIL_VALUE(regs[a+idx]);
i++;
}
}
@@ -2253,6 +2256,7 @@ RETRY_TRY_BLOCK:
ci->proc = p;
if (MRB_PROC_CFUNC_P(p)) {
+ ci->nregs = 0;
mrb->c->stack[0] = p->body.func(mrb, recv);
mrb_gc_arena_restore(mrb, ai);
if (mrb->exc) goto L_RAISE;
@@ -2382,6 +2386,7 @@ mrb_toplevel_run_keep(mrb_state *mrb, struct RProc *proc, unsigned int stack_kee
return mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep);
}
ci = cipush(mrb);
+ ci->nregs = 1; /* protect the receiver */
ci->acc = CI_ACC_SKIP;
ci->target_class = mrb->object_class;
v = mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep);