summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class.c45
-rw-r--r--src/codegen.c20
-rw-r--r--src/dump.c182
-rw-r--r--src/error.c28
-rw-r--r--src/etc.c1
-rw-r--r--src/hash.c4
-rw-r--r--src/kernel.c104
-rw-r--r--src/load.c110
-rw-r--r--src/numeric.c10
-rw-r--r--src/opcode.h162
-rw-r--r--src/parse.y3
-rw-r--r--src/proc.c4
-rw-r--r--src/range.c2
-rw-r--r--src/string.c40
-rw-r--r--src/symbol.c2
-rw-r--r--src/variable.c2
-rw-r--r--src/vm.c109
17 files changed, 478 insertions, 350 deletions
diff --git a/src/class.c b/src/class.c
index a4f9f2873..dd7bc4fea 100644
--- a/src/class.c
+++ b/src/class.c
@@ -26,7 +26,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
if (!h) return;
for (k = kh_begin(h); k != kh_end(h); k++) {
- if (kh_exist(h, k)){
+ if (kh_exist(h, k)) {
struct RProc *m = kh_value(h, k);
if (m) {
mrb_gc_mark(mrb, (struct RBasic*)m);
@@ -227,6 +227,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
}
switch (mrb_type(outer)) {
case MRB_TT_CLASS:
+ case MRB_TT_SCLASS:
case MRB_TT_MODULE:
break;
default:
@@ -421,8 +422,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *sp = mrb->c->stack + 1;
va_list ap;
int argc = mrb->c->ci->argc;
- mrb_bool opt = 0;
- mrb_bool given = 1;
+ mrb_bool opt = FALSE;
+ mrb_bool given = TRUE;
va_start(ap, format);
if (argc < 0) {
@@ -438,7 +439,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
default:
if (argc <= i) {
if (opt) {
- given = 0;
+ given = FALSE;
}
else {
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
@@ -669,7 +670,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
break;
case '|':
- opt = 1;
+ opt = TRUE;
break;
case '?':
{
@@ -747,7 +748,7 @@ mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
if (c != p && p->tt == MRB_TT_CLASS) {
superclass_seen = 1;
}
- else if (p->mt == m->mt){
+ else if (p->mt == m->mt) {
if (p->tt == MRB_TT_ICLASS && !superclass_seen) {
ins_pos = p;
}
@@ -1245,21 +1246,31 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
{
mrb_value path;
const char *name;
- mrb_int len;
mrb_sym classpath = mrb_intern_lit(mrb, "__classpath__");
path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath);
if (mrb_nil_p(path)) {
struct RClass *outer = mrb_class_outer_module(mrb, c);
mrb_sym sym = mrb_class_sym(mrb, c, outer);
+ mrb_int len;
+
if (sym == 0) {
return mrb_nil_value();
}
else if (outer && outer != mrb->object_class) {
mrb_value base = mrb_class_path(mrb, outer);
- path = mrb_str_plus(mrb, base, mrb_str_new_lit(mrb, "::"));
+ path = mrb_str_buf_new(mrb, 0);
+ if (mrb_nil_p(base)) {
+ mrb_str_cat_lit(mrb, path, "#<Class:");
+ mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, outer));
+ mrb_str_cat_lit(mrb, path, ">");
+ }
+ else {
+ mrb_str_concat(mrb, path, base);
+ }
+ mrb_str_cat_lit(mrb, path, "::");
name = mrb_sym2name_len(mrb, sym, &len);
- mrb_str_concat(mrb, path, mrb_str_new(mrb, name, len));
+ mrb_str_cat(mrb, path, name, len);
}
else {
name = mrb_sym2name_len(mrb, sym, &len);
@@ -1332,7 +1343,7 @@ mrb_class_new(mrb_state *mrb, struct RClass *super)
mrb_check_inheritable(mrb, super);
}
c = boot_defclass(mrb, super);
- if (super){
+ if (super) {
MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
}
make_metaclass(mrb, c);
@@ -1698,7 +1709,7 @@ mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
val = mrb_iv_remove(mrb, mod, id);
if (!mrb_undef_p(val)) return val;
- if (mrb_cv_defined(mrb, mod, id)){
+ if (mrb_cv_defined(mrb, mod, id)) {
mrb_name_error(mrb, id, "cannot remove %S for %S",
mrb_sym2str(mrb, id), mod);
}
@@ -1890,8 +1901,16 @@ mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
mrb_sym sym;
mrb_get_args(mrb, "n", &sym);
- mrb_name_error(mrb, sym, "uninitialized constant %S",
- mrb_sym2str(mrb, sym));
+
+ if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
+ mrb_name_error(mrb, sym, "uninitialized constant %S::%S",
+ mod,
+ mrb_sym2str(mrb, sym));
+ }
+ else {
+ mrb_name_error(mrb, sym, "uninitialized constant %S",
+ mrb_sym2str(mrb, sym));
+ }
/* not reached */
return mrb_nil_value();
}
diff --git a/src/codegen.c b/src/codegen.c
index 0347f8e7a..cec0d226f 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -15,7 +15,7 @@
#include "mruby/string.h"
#include "mruby/debug.h"
#include "node.h"
-#include "opcode.h"
+#include "mruby/opcode.h"
#include "mruby/re.h"
#include "mrb_throw.h"
@@ -66,8 +66,8 @@ typedef struct scope {
size_t scapa;
size_t rcapa;
- int nlocals;
- int nregs;
+ uint16_t nlocals;
+ uint16_t nregs;
int ai;
int debug_start_pos;
@@ -2500,11 +2500,17 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
node *n = lv;
size_t i = 0;
- p->irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals)*p->nlocals);
+ p->irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (p->nlocals - 1));
for (i=0, n=lv; n; i++,n=n->cdr) {
p->irep->lv[i].name = lv_name(n);
- p->irep->lv[i].r = lv_idx(p, lv_name(n));
+ if (lv_name(n)) {
+ p->irep->lv[i].r = lv_idx(p, lv_name(n));
+ }
+ else {
+ p->irep->lv[i].r = 0;
+ }
}
+ mrb_assert(i + 1 == p->nlocals);
}
p->ai = mrb_gc_arena_save(mrb);
@@ -2637,6 +2643,7 @@ loop_pop(codegen_scope *s, int val)
if (val) push();
}
+#ifdef ENABLE_STDIO
static int
print_r(mrb_state *mrb, mrb_irep *irep, size_t n, int pre)
{
@@ -2679,6 +2686,7 @@ print_lv(mrb_state *mrb, mrb_irep *irep, mrb_code c, int r)
}
printf("\n");
}
+#endif
static void
codedump(mrb_state *mrb, mrb_irep *irep)
@@ -2754,7 +2762,7 @@ codedump(mrb_state *mrb, mrb_irep *irep)
print_lv(mrb, irep, c, RA);
break;
case OP_GETGLOBAL:
- printf("OP_GETGLOBAL\tR%d\t:%s\n", GETARG_A(c),
+ printf("OP_GETGLOBAL\tR%d\t:%s", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
print_lv(mrb, irep, c, RA);
break;
diff --git a/src/dump.c b/src/dump.c
index 09ac80fac..564c6888e 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -500,7 +500,7 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
}
static int
-find_filename_index(const mrb_sym *ary, uint16_t ary_len, mrb_sym s)
+find_filename_index(const mrb_sym *ary, int ary_len, mrb_sym s)
{
int i;
@@ -692,6 +692,148 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur)
return MRB_DUMP_OK;
}
+static void
+create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len)
+{
+ size_t i;
+
+ if (*syms == NULL) {
+ *syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * 1);
+ }
+
+ for (i = 0; i + 1 < irep->nlocals; ++i) {
+ mrb_sym const name = irep->lv[i].name;
+ if (name == 0) continue;
+ if (find_filename_index(*syms, *syms_len, name) != -1) continue;
+
+ ++(*syms_len);
+ *syms = (mrb_sym*)mrb_realloc(mrb, *syms, sizeof(mrb_sym) * (*syms_len));
+ (*syms)[*syms_len - 1] = name;
+ }
+
+ for (i = 0; i < irep->rlen; ++i) {
+ create_lv_sym_table(mrb, irep->reps[i], syms, syms_len);
+ }
+}
+
+static int
+write_lv_sym_table(mrb_state *mrb, uint8_t **start, mrb_sym const *syms, uint32_t syms_len)
+{
+ uint8_t *cur = *start;
+ uint32_t i;
+ const char *str;
+ mrb_int str_len;
+
+ cur += uint32_to_bin(syms_len, cur);
+
+ for (i = 0; i < syms_len; ++i) {
+ str = mrb_sym2name_len(mrb, syms[i], &str_len);
+ cur += uint16_to_bin(str_len, cur);
+ memcpy(cur, str, str_len);
+ cur += str_len;
+ }
+
+ *start = cur;
+
+ return MRB_DUMP_OK;
+}
+
+static int
+write_lv_record(mrb_state *mrb, const mrb_irep *irep, uint8_t **start, mrb_sym const *syms, uint32_t syms_len)
+{
+ uint8_t *cur = *start;
+ size_t i;
+
+ for (i = 0; i + 1 < irep->nlocals; ++i) {
+ if (irep->lv[i].name == 0) {
+ cur += uint16_to_bin(RITE_LV_NULL_MARK, cur);
+ cur += uint16_to_bin(0, cur);
+ }
+ else {
+ int const sym_idx = find_filename_index(syms, syms_len, irep->lv[i].name);
+ mrb_assert(sym_idx != -1); /* local variable name must be in syms */
+
+ cur += uint16_to_bin(sym_idx, cur);
+ cur += uint16_to_bin(irep->lv[i].r, cur);
+ }
+ }
+
+ for (i = 0; i < irep->rlen; ++i) {
+ write_lv_record(mrb, irep->reps[i], &cur, syms, syms_len);
+ }
+
+ *start = cur;
+
+ return MRB_DUMP_OK;
+}
+
+static size_t
+get_lv_record_size(mrb_state *mrb, mrb_irep *irep)
+{
+ size_t ret = 0, i;
+
+ ret += (sizeof(uint16_t) + sizeof(uint16_t)) * (irep->nlocals - 1);
+
+ for (i = 0; i < irep->rlen; ++i) {
+ ret += get_lv_record_size(mrb, irep->reps[i]);
+ }
+
+ return ret;
+}
+
+static size_t
+get_lv_section_size(mrb_state *mrb, mrb_irep *irep, mrb_sym const *syms, uint32_t syms_len)
+{
+ size_t ret = 0, i;
+
+ ret += sizeof(uint32_t); /* syms_len */
+ ret += sizeof(uint16_t) * syms_len; /* symbol name lengths */
+ for (i = 0; i < syms_len; ++i) {
+ mrb_int str_len;
+ mrb_sym2name_len(mrb, syms[i], &str_len);
+ ret += str_len;
+ }
+
+ ret += get_lv_record_size(mrb, irep);
+
+ return ret;
+}
+
+static int
+write_section_lv(mrb_state *mrb, mrb_irep *irep, uint8_t *start, mrb_sym const *syms, uint32_t const syms_len)
+{
+ uint8_t *cur = start;
+ struct rite_section_lv_header *header;
+ ptrdiff_t diff;
+ int result = MRB_DUMP_OK;
+
+ if (mrb == NULL || cur == NULL) {
+ return MRB_DUMP_INVALID_ARGUMENT;
+ }
+
+ header = (struct rite_section_lv_header*)cur;
+ cur += sizeof(struct rite_section_lv_header);
+
+ result = write_lv_sym_table(mrb, &cur, syms, syms_len);
+ if (result != MRB_DUMP_OK) {
+ goto lv_section_exit;
+ }
+
+ result = write_lv_record(mrb, irep, &cur, syms, syms_len);
+ if (result != MRB_DUMP_OK) {
+ goto lv_section_exit;
+ }
+
+ memcpy(header->section_identify, RITE_SECTION_LV_IDENTIFIER, sizeof(header->section_identify));
+
+ diff = cur - start;
+ mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+ uint32_to_bin(diff, header->section_size);
+
+lv_section_exit:
+ return result;
+}
+
static int
write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin)
{
@@ -725,14 +867,29 @@ is_debug_info_defined(mrb_irep *irep)
return TRUE;
}
+static mrb_bool
+is_lv_defined(mrb_irep *irep)
+{
+ size_t i;
+
+ if (irep->lv) { return TRUE; }
+
+ for (i = 0; i < irep->rlen; ++i) {
+ if (is_lv_defined(irep->reps[i])) { return TRUE; }
+ }
+
+ return FALSE;
+}
+
int
mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size)
{
int result = MRB_DUMP_GENERAL_FAILURE;
size_t section_irep_size;
- size_t section_lineno_size = 0;
+ size_t section_lineno_size = 0, section_lv_size = 0;
uint8_t *cur = NULL;
- mrb_bool const debug_info_defined = is_debug_info_defined(irep);
+ mrb_bool const debug_info_defined = is_debug_info_defined(irep), lv_defined = is_lv_defined(irep);
+ mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0;
if (mrb == NULL) {
*bin = NULL;
@@ -764,8 +921,14 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
}
}
+ if (lv_defined) {
+ section_lv_size += sizeof(struct rite_section_lv_header);
+ create_lv_sym_table(mrb, irep, &lv_syms, &lv_syms_len);
+ section_lv_size += get_lv_section_size(mrb, irep, lv_syms, lv_syms_len);
+ }
+
*bin_size = sizeof(struct rite_binary_header) +
- section_irep_size + section_lineno_size +
+ 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) {
@@ -793,6 +956,14 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
cur += section_lineno_size;
}
+ if (lv_defined) {
+ result = write_section_lv(mrb, irep, cur, lv_syms, lv_syms_len);
+ if (result != MRB_DUMP_OK) {
+ goto error_exit;
+ }
+ cur += section_lv_size;
+ }
+
write_footer(mrb, cur);
write_rite_binary_header(mrb, *bin_size, *bin);
@@ -801,6 +972,9 @@ error_exit:
mrb_free(mrb, *bin);
*bin = NULL;
}
+ if (lv_syms) {
+ mrb_free(mrb, lv_syms);
+ }
return result;
}
diff --git a/src/error.c b/src/error.c
index 6f7641cf1..360df8f2e 100644
--- a/src/error.c
+++ b/src/error.c
@@ -176,7 +176,7 @@ exc_equal(mrb_state *mrb, mrb_value exc)
mrb_get_args(mrb, "o", &obj);
if (mrb_obj_equal(mrb, exc, obj)) {
- equal_p = 1;
+ equal_p = TRUE;
}
else {
if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
@@ -445,20 +445,20 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg)
void
mrb_init_exception(mrb_state *mrb)
{
- struct RClass *e;
-
- mrb->eException_class = e = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
- mrb_define_class_method(mrb, e, "exception", mrb_instance_new, MRB_ARGS_ANY());
- mrb_define_method(mrb, e, "exception", exc_exception, MRB_ARGS_ANY());
- mrb_define_method(mrb, e, "initialize", exc_initialize, MRB_ARGS_ANY());
- mrb_define_method(mrb, e, "==", exc_equal, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, e, "to_s", exc_to_s, MRB_ARGS_NONE());
- mrb_define_method(mrb, e, "message", exc_message, MRB_ARGS_NONE());
- mrb_define_method(mrb, e, "inspect", exc_inspect, MRB_ARGS_NONE());
- mrb_define_method(mrb, e, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE());
+ struct RClass *exception, *script_error;
+
+ mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
+ mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_ANY());
+ mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_ANY());
+ mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_ANY());
+ mrb_define_method(mrb, exception, "==", exc_equal, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE());
+ mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE());
+ mrb_define_method(mrb, exception, "inspect", exc_inspect, MRB_ARGS_NONE());
+ mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE());
mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
- e = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */
- mrb_define_class(mrb, "SyntaxError", e); /* 15.2.38 */
+ script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */
+ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */
}
diff --git a/src/etc.c b/src/etc.c
index 58b1c91c0..bc5d116a0 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -9,6 +9,7 @@
#include "mruby/data.h"
#include "mruby/class.h"
#include "mruby/re.h"
+#include "mruby/irep.h"
struct RData*
mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb_data_type *type)
diff --git a/src/hash.c b/src/hash.c
index 8e6be2214..997610953 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -678,7 +678,7 @@ mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_hash_to_hash(mrb_state *mrb, mrb_value hash)
{
- return hash;
+ return hash;
}
/* 15.2.13.4.19 */
@@ -739,7 +739,7 @@ mrb_hash_values(mrb_state *mrb, mrb_value hash)
if (!h) return mrb_ary_new(mrb);
ary = mrb_ary_new_capa(mrb, kh_size(h));
for (k = kh_begin(h); k != kh_end(h); k++) {
- if (kh_exist(h, k)){
+ if (kh_exist(h, k)) {
mrb_hash_value hv = kh_value(h,k);
mrb_ary_set(mrb, ary, hv.n, hv.v);
diff --git a/src/kernel.c b/src/kernel.c
index d759661d4..0a608bcb0 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -93,24 +93,18 @@ static mrb_value
mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
- mrb_bool eql_p;
mrb_get_args(mrb, "o", &arg);
- eql_p = mrb_obj_equal(mrb, self, arg);
-
- return mrb_bool_value(eql_p);
+ return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
}
static mrb_value
mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
- mrb_bool eql_p;
mrb_get_args(mrb, "o", &arg);
- eql_p = mrb_equal(mrb, self, arg);
-
- return mrb_bool_value(!eql_p);
+ return mrb_bool_value(!mrb_equal(mrb, self, arg));
}
/* 15.3.1.3.2 */
@@ -126,12 +120,9 @@ static mrb_value
mrb_equal_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
- mrb_bool equal_p;
mrb_get_args(mrb, "o", &arg);
- equal_p = mrb_equal(mrb, self, arg);
-
- return mrb_bool_value(equal_p);
+ return mrb_bool_value(mrb_equal(mrb, self, arg));
}
/* 15.3.1.3.3 */
@@ -210,26 +201,6 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
return mrb_bool_value(given_p);
}
-/*
- * call-seq:
- * __method__ -> symbol
- *
- * Returns the name at the definition of the current method as a
- * Symbol.
- * If called outside of a method, it returns <code>nil</code>.
- *
- */
-static mrb_value
-mrb_f_method(mrb_state *mrb, mrb_value self)
-{
- mrb_callinfo *ci = mrb->c->ci;
- ci--;
- if (ci->mid)
- return mrb_symbol_value(ci->mid);
- else
- return mrb_nil_value();
-}
-
/* 15.3.1.3.7 */
/*
* call-seq:
@@ -296,21 +267,21 @@ static void
init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
{
switch (mrb_type(obj)) {
- case MRB_TT_CLASS:
- case MRB_TT_MODULE:
- copy_class(mrb, dest, obj);
- /* fall through */
- case MRB_TT_OBJECT:
- case MRB_TT_SCLASS:
- case MRB_TT_HASH:
- case MRB_TT_DATA:
- mrb_iv_copy(mrb, dest, obj);
- break;
-
- default:
- break;
- }
- mrb_funcall(mrb, dest, "initialize_copy", 1, obj);
+ case MRB_TT_CLASS:
+ case MRB_TT_MODULE:
+ copy_class(mrb, dest, obj);
+ /* fall through */
+ case MRB_TT_OBJECT:
+ case MRB_TT_SCLASS:
+ case MRB_TT_HASH:
+ case MRB_TT_DATA:
+ mrb_iv_copy(mrb, dest, obj);
+ break;
+
+ default:
+ break;
+ }
+ mrb_funcall(mrb, dest, "initialize_copy", 1, obj);
}
/* 15.3.1.3.8 */
@@ -346,7 +317,7 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
mrb_value clone;
if (mrb_special_const_p(self)) {
- mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
+ mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
}
p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
p->c = mrb_singleton_class_clone(mrb, self);
@@ -378,17 +349,17 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
mrb_value
mrb_obj_dup(mrb_state *mrb, mrb_value obj)
{
- struct RBasic *p;
- mrb_value dup;
+ struct RBasic *p;
+ mrb_value dup;
- if (mrb_special_const_p(obj)) {
- mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
- }
- p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
- dup = mrb_obj_value(p);
- init_copy(mrb, dup, obj);
+ if (mrb_special_const_p(obj)) {
+ mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
+ }
+ p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
+ dup = mrb_obj_value(p);
+ init_copy(mrb, dup, obj);
- return dup;
+ return dup;
}
static mrb_value
@@ -1013,16 +984,11 @@ basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
static mrb_value
obj_respond_to(mrb_state *mrb, mrb_value self)
{
- mrb_value *argv;
- mrb_int argc;
- mrb_value mid, priv;
+ mrb_value mid;
mrb_sym id, rtm_id;
- mrb_bool respond_to_p = TRUE;
+ mrb_bool priv = FALSE, respond_to_p = TRUE;
- mrb_get_args(mrb, "*", &argv, &argc);
- mid = argv[0];
- if (argc > 1) priv = argv[1];
- else priv = mrb_nil_value();
+ mrb_get_args(mrb, "o|b", &mid, &priv);
if (mrb_symbol_p(mid)) {
id = mrb_symbol(mid);
@@ -1046,13 +1012,14 @@ obj_respond_to(mrb_state *mrb, mrb_value self)
}
if (respond_to_p) {
- respond_to_p = basic_obj_respond_to(mrb, self, id, !mrb_test(priv));
+ respond_to_p = basic_obj_respond_to(mrb, self, id, !priv);
}
if (!respond_to_p) {
rtm_id = mrb_intern_lit(mrb, "respond_to_missing?");
- if (basic_obj_respond_to(mrb, self, rtm_id, !mrb_test(priv))) {
- return mrb_funcall_argv(mrb, self, rtm_id, argc, argv);
+ if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) {
+ mrb_value args[] = { mid, mrb_bool_value(priv) };
+ return mrb_funcall_argv(mrb, self, rtm_id, 2, args);
}
}
return mrb_bool_value(respond_to_p);
@@ -1153,7 +1120,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "===", mrb_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */
mrb_define_method(mrb, krn, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.3 */
mrb_define_method(mrb, krn, "__send__", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.4 */
- mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
mrb_define_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.6 */
mrb_define_method(mrb, krn, "class", mrb_obj_class_m, MRB_ARGS_NONE()); /* 15.3.1.3.7 */
mrb_define_method(mrb, krn, "clone", mrb_obj_clone, MRB_ARGS_NONE()); /* 15.3.1.3.8 */
diff --git a/src/load.c b/src/load.c
index 1142a6eaf..0a877dd78 100644
--- a/src/load.c
+++ b/src/load.c
@@ -400,6 +400,92 @@ debug_exit:
}
static int
+read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *record_len, mrb_sym const *syms, uint32_t syms_len)
+{
+ const uint8_t *bin = start;
+ size_t i;
+ ptrdiff_t diff;
+
+ irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (irep->nlocals - 1));
+
+ for (i = 0; i + 1< irep->nlocals; ++i) {
+ uint16_t const sym_idx = bin_to_uint16(bin);
+ bin += sizeof(uint16_t);
+ if (sym_idx == RITE_LV_NULL_MARK) {
+ irep->lv[i].name = 0;
+ irep->lv[i].r = 0;
+ }
+ else {
+ if (sym_idx >= syms_len) {
+ return MRB_DUMP_GENERAL_FAILURE;
+ }
+ irep->lv[i].name = syms[sym_idx];
+
+ irep->lv[i].r = bin_to_uint16(bin);
+ }
+ bin += sizeof(uint16_t);
+ }
+
+ for (i = 0; i < irep->rlen; ++i) {
+ size_t len;
+ int ret;
+
+ ret = read_lv_record(mrb, bin, irep->reps[i], &len, syms, syms_len);
+ if (ret != MRB_DUMP_OK) return ret;
+ bin += len;
+ }
+
+ diff = bin - start;
+ mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+ *record_len = (size_t)diff;
+
+ return MRB_DUMP_OK;
+}
+
+static int
+read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc)
+{
+ const uint8_t *bin;
+ ptrdiff_t diff;
+ struct rite_section_lv_header const *header;
+ uint32_t i;
+ size_t len = 0;
+ 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;
+
+ bin = start;
+ header = (struct rite_section_lv_header const*)bin;
+ bin += sizeof(struct rite_section_lv_header);
+
+ syms_len = bin_to_uint32(bin);
+ bin += sizeof(uint32_t);
+ syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)syms_len);
+ for (i = 0; i < syms_len; ++i) {
+ uint16_t const str_len = bin_to_uint16(bin);
+ bin += sizeof(uint16_t);
+
+ syms[i] = intern_func(mrb, (const char*)bin, str_len);
+ bin += str_len;
+ }
+
+ result = read_lv_record(mrb, bin, irep, &len, syms, syms_len);
+ if (result != MRB_DUMP_OK) goto lv_exit;
+
+ bin += len;
+ diff = bin - start;
+ mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+ if ((uint32_t)diff != bin_to_uint32(header->section_size)) {
+ result = MRB_DUMP_GENERAL_FAILURE;
+ }
+
+lv_exit:
+ mrb_free(mrb, syms);
+ return result;
+}
+
+static int
read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc)
{
const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
@@ -465,6 +551,13 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
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);
+ if (result < MRB_DUMP_OK) {
+ return NULL;
+ }
+ }
bin += bin_to_uint32(section_header->section_size);
} while (memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0);
@@ -630,7 +723,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
/* verify CRC */
fpos = ftell(fp);
/* You don't need use SIZE_ERROR as block_size is enough small. */
- for (i = 0; i < block_fallback_count; i++,block_size >>= 1){
+ for (i = 0; i < block_fallback_count; i++,block_size >>= 1) {
buf = (uint8_t*)mrb_malloc_simple(mrb, block_size);
if (buf) break;
}
@@ -684,6 +777,21 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
}
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;
+ else {
+ uint8_t* const bin = (uint8_t*)mrb_malloc(mrb, section_size);
+
+ fseek(fp, fpos, SEEK_SET);
+ if (fread((char*)bin, section_size, 1, fp) != 1) {
+ mrb_free(mrb, bin);
+ return NULL;
+ }
+ result = read_section_lv(mrb, bin, irep, TRUE);
+ mrb_free(mrb, bin);
+ }
+ if (result < MRB_DUMP_OK) return NULL;
+ }
fseek(fp, fpos + section_size, SEEK_SET);
} while (memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0);
diff --git a/src/numeric.c b/src/numeric.c
index 357e9438e..db1e7d0f4 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -687,7 +687,11 @@ int_to_i(mrb_state *mrb, mrb_value num)
return num;
}
+#ifdef MRB_FIXNUM_SHIFT
+#define SQRT_INT_MAX ((mrb_int)1<<((MRB_INT_BIT-1-MRB_FIXNUM_SHIFT)/2))
+#else
#define SQRT_INT_MAX ((mrb_int)1<<((MRB_INT_BIT-1)/2))
+#endif
/*tests if N*N would overflow*/
#define FIT_SQRT_INT(n) (((n)<SQRT_INT_MAX)&&((n)>=-SQRT_INT_MAX))
@@ -698,14 +702,15 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
a = mrb_fixnum(x);
if (mrb_fixnum_p(y)) {
- mrb_int b, c;
+ mrb_float c;
+ mrb_int b;
if (a == 0) return x;
b = mrb_fixnum(y);
if (FIT_SQRT_INT(a) && FIT_SQRT_INT(b))
return mrb_fixnum_value(a*b);
c = a * b;
- if (a != 0 && c/a != b) {
+ if ((a != 0 && c/a != b) || !FIXABLE(c)) {
return mrb_float_value(mrb, (mrb_float)a*(mrb_float)b);
}
return mrb_fixnum_value(c);
@@ -1303,6 +1308,7 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */
mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE());
+ /* Fixnum Class */
fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer);
mrb_define_method(mrb, fixnum, "+", fix_plus, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */
mrb_define_method(mrb, fixnum, "-", fix_minus, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */
diff --git a/src/opcode.h b/src/opcode.h
index 8b14af155..2446f92ed 100644
--- a/src/opcode.h
+++ b/src/opcode.h
@@ -1,160 +1,2 @@
-/*
-** opcode.h - RiteVM operation codes
-**
-** See Copyright Notice in mruby.h
-*/
-
-#ifndef OPCODE_H
-#define OPCODE_H
-
-#define MAXARG_Bx (0xffff)
-#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
-
-/* instructions: packed 32 bit */
-/* ------------------------------- */
-/* A:B:C:OP = 9: 9: 7: 7 */
-/* A:Bx:OP = 9:16: 7 */
-/* Ax:OP = 25: 7 */
-/* A:Bz:Cz:OP = 9:14: 2: 7 */
-
-#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f))
-#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
-#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
-#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f))
-#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff))
-#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx))
-#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff))
-#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1))))
-#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1))))
-#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
-#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
-
-#define MKOPCODE(op) ((op) & 0x7f)
-#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23)
-#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14)
-#define MKARG_C(c) (((c) & 0x7f) << 7)
-#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7)
-#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx)
-#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7)
-#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
-#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2)
-
-#define MKOP_A(op,a) (MKOPCODE(op)|MKARG_A(a))
-#define MKOP_AB(op,a,b) (MKOP_A(op,a)|MKARG_B(b))
-#define MKOP_ABC(op,a,b,c) (MKOP_AB(op,a,b)|MKARG_C(c))
-#define MKOP_ABx(op,a,bx) (MKOP_A(op,a)|MKARG_Bx(bx))
-#define MKOP_Bx(op,bx) (MKOPCODE(op)|MKARG_Bx(bx))
-#define MKOP_sBx(op,sbx) (MKOPCODE(op)|MKARG_sBx(sbx))
-#define MKOP_AsBx(op,a,sbx) (MKOP_A(op,a)|MKARG_sBx(sbx))
-#define MKOP_Ax(op,ax) (MKOPCODE(op)|MKARG_Ax(ax))
-#define MKOP_Abc(op,a,b,c) (MKOP_A(op,a)|MKARG_bc(b,c))
-
-enum {
- /*-----------------------------------------------------------------------
- operation code operand description
- ------------------------------------------------------------------------*/
- OP_NOP=0,/* */
- OP_MOVE,/* A B R(A) := R(B) */
- OP_LOADL,/* A Bx R(A) := Lit(Bx) */
- OP_LOADI,/* A sBx R(A) := sBx */
- OP_LOADSYM,/* A Bx R(A) := Sym(Bx) */
- OP_LOADNIL,/* A R(A) := nil */
- OP_LOADSELF,/* A R(A) := self */
- OP_LOADT,/* A R(A) := true */
- OP_LOADF,/* A R(A) := false */
-
- OP_GETGLOBAL,/* A Bx R(A) := getglobal(Sym(Bx)) */
- OP_SETGLOBAL,/* A Bx setglobal(Sym(Bx), R(A)) */
- OP_GETSPECIAL,/*A Bx R(A) := Special[Bx] */
- OP_SETSPECIAL,/*A Bx Special[Bx] := R(A) */
- OP_GETIV,/* A Bx R(A) := ivget(Sym(Bx)) */
- OP_SETIV,/* A Bx ivset(Sym(Bx),R(A)) */
- OP_GETCV,/* A Bx R(A) := cvget(Sym(Bx)) */
- OP_SETCV,/* A Bx cvset(Sym(Bx),R(A)) */
- OP_GETCONST,/* A Bx R(A) := constget(Sym(Bx)) */
- OP_SETCONST,/* A Bx constset(Sym(Bx),R(A)) */
- OP_GETMCNST,/* A Bx R(A) := R(A)::Sym(Bx) */
- OP_SETMCNST,/* A Bx R(A+1)::Sym(Bx) := R(A) */
- OP_GETUPVAR,/* A B C R(A) := uvget(B,C) */
- OP_SETUPVAR,/* A B C uvset(B,C,R(A)) */
-
- OP_JMP,/* sBx pc+=sBx */
- OP_JMPIF,/* A sBx if R(A) pc+=sBx */
- OP_JMPNOT,/* A sBx if !R(A) pc+=sBx */
- OP_ONERR,/* sBx rescue_push(pc+sBx) */
- OP_RESCUE,/* A clear(exc); R(A) := exception (ignore when A=0) */
- OP_POPERR,/* A A.times{rescue_pop()} */
- OP_RAISE,/* A raise(R(A)) */
- OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */
- OP_EPOP,/* A A.times{ensure_pop().call} */
-
- OP_SEND,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
- OP_SENDB,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C),&R(A+C+1))*/
- OP_FSEND,/* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
- OP_CALL,/* A B C R(A) := self.call(R(A),.., R(A+C)) */
- OP_SUPER,/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
- OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */
- OP_ENTER,/* Ax arg setup according to flags (23=5:5:1:5:5:1:1) */
- OP_KARG,/* A B C R(A) := kdict[mSym(B)]; if C kdict.rm(mSym(B)) */
- OP_KDICT,/* A C R(A) := kdict */
-
- OP_RETURN,/* A B return R(A) (B=normal,in-block return/break) */
- OP_TAILCALL,/* A B C return call(R(A),mSym(B),*R(C)) */
- OP_BLKPUSH,/* A Bx R(A) := block (16=6:1:5:4) */
-
- OP_ADD,/* A B C R(A) := R(A)+R(A+1) (mSyms[B]=:+,C=1) */
- OP_ADDI,/* A B C R(A) := R(A)+C (mSyms[B]=:+) */
- OP_SUB,/* A B C R(A) := R(A)-R(A+1) (mSyms[B]=:-,C=1) */
- OP_SUBI,/* A B C R(A) := R(A)-C (mSyms[B]=:-) */
- OP_MUL,/* A B C R(A) := R(A)*R(A+1) (mSyms[B]=:*,C=1) */
- OP_DIV,/* A B C R(A) := R(A)/R(A+1) (mSyms[B]=:/,C=1) */
- OP_EQ,/* A B C R(A) := R(A)==R(A+1) (mSyms[B]=:==,C=1) */
- OP_LT,/* A B C R(A) := R(A)<R(A+1) (mSyms[B]=:<,C=1) */
- OP_LE,/* A B C R(A) := R(A)<=R(A+1) (mSyms[B]=:<=,C=1) */
- OP_GT,/* A B C R(A) := R(A)>R(A+1) (mSyms[B]=:>,C=1) */
- OP_GE,/* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */
-
- OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
- OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */
- OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */
- OP_AREF,/* A B C R(A) := R(B)[C] */
- OP_ASET,/* A B C R(B)[C] := R(A) */
- OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */
-
- OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */
- OP_STRCAT,/* A B str_cat(R(A),R(B)) */
-
- OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
- OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cz) */
- OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */
-
- OP_OCLASS,/* A R(A) := ::Object */
- OP_CLASS,/* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */
- OP_MODULE,/* A B R(A) := newmodule(R(A),mSym(B)) */
- OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */
- OP_METHOD,/* A B R(A).newmethod(mSym(B),R(A+1)) */
- OP_SCLASS,/* A B R(A) := R(B).singleton_class */
- OP_TCLASS,/* A R(A) := target_class */
-
- OP_DEBUG,/* A print R(A) */
- OP_STOP,/* stop VM */
- OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */
-
- OP_RSVD1,/* reserved instruction #1 */
- OP_RSVD2,/* reserved instruction #2 */
- OP_RSVD3,/* reserved instruction #3 */
- OP_RSVD4,/* reserved instruction #4 */
- OP_RSVD5,/* reserved instruction #5 */
-};
-
-#define OP_L_STRICT 1
-#define OP_L_CAPTURE 2
-#define OP_L_METHOD OP_L_STRICT
-#define OP_L_LAMBDA (OP_L_STRICT|OP_L_CAPTURE)
-#define OP_L_BLOCK OP_L_CAPTURE
-
-#define OP_R_NORMAL 0
-#define OP_R_BREAK 1
-#define OP_R_RETURN 2
-
-#endif /* OPCODE_H */
+/* this header file is to be removed soon. */
+#include "mruby/opcode.h"
diff --git a/src/parse.y b/src/parse.y
index 205405065..217289aff 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -5472,7 +5472,8 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
p->filename_table[p->filename_table_length - 1] = sym;
}
-char const* mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
+char const*
+mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
if (idx >= p->filename_table_length) { return NULL; }
else {
return mrb_sym2name_len(p->mrb, p->filename_table[idx], NULL);
diff --git a/src/proc.c b/src/proc.c
index fa4c28fc8..d4fe86680 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -7,7 +7,7 @@
#include "mruby.h"
#include "mruby/class.h"
#include "mruby/proc.h"
-#include "opcode.h"
+#include "mruby/opcode.h"
static mrb_code call_iseq[] = {
MKOP_A(OP_CALL, 0),
@@ -91,7 +91,7 @@ mrb_proc_copy(struct RProc *a, struct RProc *b)
a->body = b->body;
if (!MRB_PROC_CFUNC_P(a)) {
a->body.irep->refcnt++;
- };
+ }
a->target_class = b->target_class;
a->env = b->env;
}
diff --git a/src/range.c b/src/range.c
index 3e5af1894..e162fb63f 100644
--- a/src/range.c
+++ b/src/range.c
@@ -126,7 +126,7 @@ mrb_range_initialize(mrb_state *mrb, mrb_value range)
n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
if (n != 3) {
- exclusive = 0;
+ exclusive = FALSE;
}
/* Ranges are immutable, so that they should be initialized only once. */
range_init(mrb, range, beg, end, exclusive);
diff --git a/src/string.c b/src/string.c
index d5a849cec..1572cab14 100644
--- a/src/string.c
+++ b/src/string.c
@@ -257,11 +257,11 @@ str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
total = STR_LEN(s)+len;
if (capa <= total) {
while (total > capa) {
- if (capa + 1 >= MRB_INT_MAX / 2) {
- capa = (total + 4095) / 4096;
- break;
- }
- capa = (capa + 1) * 2;
+ if (capa + 1 >= MRB_INT_MAX / 2) {
+ capa = (total + 4095) / 4096;
+ break;
+ }
+ capa = (capa + 1) * 2;
}
resize_capa(mrb, s, capa);
}
@@ -277,10 +277,7 @@ str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
mrb_value
mrb_str_new(mrb_state *mrb, const char *p, size_t len)
{
- struct RString *s;
-
- s = str_new(mrb, p, len);
- return mrb_obj_value(s);
+ return mrb_obj_value(str_new(mrb, p, len));
}
/*
@@ -341,7 +338,7 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0)
struct RString *s;
if (!mrb_string_p(str0)) {
- mrb_raise(mrb, E_TYPE_ERROR, "expected String");
+ mrb_raise(mrb, E_TYPE_ERROR, "expected String");
}
s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0));
@@ -666,12 +663,10 @@ static mrb_value
mrb_str_equal_m(mrb_state *mrb, mrb_value str1)
{
mrb_value str2;
- mrb_bool equal_p;
mrb_get_args(mrb, "o", &str2);
- equal_p = mrb_str_equal(mrb, str1, str2);
- return mrb_bool_value(equal_p);
+ return mrb_bool_value(mrb_str_equal(mrb, str1, str2));
}
/* ---------------------------------- */
mrb_value
@@ -692,8 +687,8 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
char *
mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr)
{
- mrb_value str = mrb_str_to_str(mrb, ptr);
- return RSTRING_PTR(str);
+ mrb_value str = mrb_str_to_str(mrb, ptr);
+ return RSTRING_PTR(str);
}
static mrb_value
@@ -723,7 +718,7 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr
qstable[i] = m + 1;
for (; x < xe; ++x)
qstable[*x] = xe - x;
- /* Searching */
+ /* Searching */
for (; y + m <= ys + n; y += *(qstable + y[m])) {
if (*xs == *y && memcmp(xs, y, m) == 0)
return y - ys;
@@ -828,8 +823,8 @@ num_index:
default:
idx = mrb_fixnum(indx);
goto num_index;
- }
- return mrb_nil_value(); /* not reached */
+ }
+ return mrb_nil_value(); /* not reached */
}
/* 15.2.10.5.6 */
@@ -1351,7 +1346,6 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
sub = argv[0];
else
sub = mrb_nil_value();
-
}
regexp_check(mrb, sub);
if (pos < 0) {
@@ -1490,11 +1484,7 @@ mrb_str_init(mrb_state *mrb, mrb_value self)
mrb_value
mrb_str_intern(mrb_state *mrb, mrb_value self)
{
- mrb_sym id;
-
- id = mrb_intern_str(mrb, self);
- return mrb_symbol_value(id);
-
+ return mrb_symbol_value(mrb_intern_str(mrb, self));
}
/* ---------------------------------- */
mrb_value
@@ -1831,7 +1821,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
else {
if (mrb_string_p(spat)) {
split_type = string;
- if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' '){
+ if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
split_type = awk;
}
}
diff --git a/src/symbol.c b/src/symbol.c
index cf8f549c5..148adc6fe 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -43,7 +43,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
mrb_sym sym;
char *p;
- if (len > UINT16_MAX) {
+ if (len > (UINT16_MAX-1)) { /* UINT16_MAX is reverved */
mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long");
}
sname.lit = lit;
diff --git a/src/variable.c b/src/variable.c
index f34735e75..5f762dd0b 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -353,7 +353,7 @@ iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
if (h) {
for (k = kh_begin(h); k != kh_end(h); k++) {
- if (kh_exist(h, k)){
+ if (kh_exist(h, k)) {
n = (*func)(mrb, kh_key(h, k), kh_value(h, k), p);
if (n > 0) return FALSE;
if (n < 0) {
diff --git a/src/vm.c b/src/vm.c
index 620f9e977..503d2c929 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -18,7 +18,7 @@
#include "mruby/string.h"
#include "mruby/variable.h"
#include "mruby/error.h"
-#include "opcode.h"
+#include "mruby/opcode.h"
#include "value_array.h"
#include "mrb_throw.h"
@@ -724,13 +724,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_LOADI) {
- /* A Bx R(A) := sBx */
+ /* A sBx R(A) := sBx */
SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i));
NEXT;
}
CASE(OP_LOADSYM) {
- /* A B R(A) := Sym(B) */
+ /* A Bx R(A) := Syms(Bx) */
SET_SYM_VALUE(regs[GETARG_A(i)], syms[GETARG_Bx(i)]);
NEXT;
}
@@ -754,13 +754,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_GETGLOBAL) {
- /* A B R(A) := getglobal(Sym(B)) */
+ /* A Bx R(A) := getglobal(Syms(Bx)) */
regs[GETARG_A(i)] = mrb_gv_get(mrb, syms[GETARG_Bx(i)]);
NEXT;
}
CASE(OP_SETGLOBAL) {
- /* setglobal(Sym(b), R(A)) */
+ /* setglobal(Syms(Bx), R(A)) */
mrb_gv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
NEXT;
}
@@ -784,13 +784,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_SETIV) {
- /* ivset(Sym(B),R(A)) */
+ /* ivset(Syms(Bx),R(A)) */
mrb_vm_iv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
NEXT;
}
CASE(OP_GETCV) {
- /* A B R(A) := ivget(Sym(B)) */
+ /* A Bx R(A) := cvget(Syms(Bx)) */
ERR_PC_SET(mrb, pc);
regs[GETARG_A(i)] = mrb_vm_cv_get(mrb, syms[GETARG_Bx(i)]);
ERR_PC_CLR(mrb);
@@ -798,13 +798,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_SETCV) {
- /* ivset(Sym(B),R(A)) */
+ /* cvset(Syms(Bx),R(A)) */
mrb_vm_cv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
NEXT;
}
CASE(OP_GETCONST) {
- /* A B R(A) := constget(Sym(B)) */
+ /* A Bx R(A) := constget(Syms(Bx)) */
mrb_value val;
ERR_PC_SET(mrb, pc);
@@ -816,13 +816,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_SETCONST) {
- /* A B constset(Sym(B),R(A)) */
+ /* A Bx constset(Syms(Bx),R(A)) */
mrb_vm_const_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
NEXT;
}
CASE(OP_GETMCNST) {
- /* A B C R(A) := R(C)::Sym(B) */
+ /* A Bx R(A) := R(A)::Syms(Bx) */
mrb_value val;
int a = GETARG_A(i);
@@ -835,7 +835,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_SETMCNST) {
- /* A B C R(A+1)::Sym(B) := R(A) */
+ /* A Bx R(A+1)::Syms(Bx) := R(A) */
int a = GETARG_A(i);
mrb_const_set(mrb, regs[a+1], syms[GETARG_Bx(i)], regs[a]);
@@ -861,7 +861,6 @@ RETRY_TRY_BLOCK:
CASE(OP_SETUPVAR) {
/* A B C uvset(B,C,R(A)) */
- /* A B C R(A) := uvget(B,C) */
int up = GETARG_C(i);
struct REnv *e = uvenv(mrb, up);
@@ -891,7 +890,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_JMPNOT) {
- /* A sBx if R(A) pc+=sBx */
+ /* A sBx if !R(A) pc+=sBx */
if (!mrb_test(regs[GETARG_A(i)])) {
pc += GETARG_sBx(i);
JUMP;
@@ -918,6 +917,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_POPERR) {
+ /* A A.times{rescue_pop()} */
int a = GETARG_A(i);
while (a--) {
@@ -962,7 +962,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_LOADNIL) {
- /* A B R(A) := nil */
+ /* A R(A) := nil */
int a = GETARG_A(i);
SET_NIL_VALUE(regs[a]);
@@ -970,12 +970,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_SENDB) {
+ /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/
/* fall through */
};
L_SEND:
CASE(OP_SEND) {
- /* A B C R(A) := call(R(A),Sym(B),R(A+1),... ,R(A+C-1)) */
+ /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */
int a = GETARG_A(i);
int n = GETARG_C(i);
struct RProc *m;
@@ -1077,7 +1078,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_FSEND) {
- /* A B C R(A) := fcall(R(A),Sym(B),R(A+1),... ,R(A+C)) */
+ /* A B C R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */
NEXT;
}
@@ -1141,7 +1142,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_SUPER) {
- /* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
+ /* A C R(A) := super(R(A+1),... ,R(A+C+1)) */
mrb_value recv;
mrb_callinfo *ci = mrb->c->ci;
struct RProc *m;
@@ -1268,7 +1269,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_ENTER) {
- /* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
+ /* Ax arg setup according to flags (23=5:5:1:5:5:1:1) */
/* number of optional arguments times OP_JMP should follow */
mrb_aspec ax = GETARG_Ax(i);
int m1 = (ax>>18)&0x1f;
@@ -1286,6 +1287,9 @@ RETRY_TRY_BLOCK:
int len = m1 + o + r + m2;
mrb_value *blk = &argv[argc < 0 ? 1 : argc];
+ if (!mrb_nil_p(*blk) && mrb_type(*blk) != MRB_TT_PROC) {
+ *blk = mrb_convert_type(mrb, *blk, MRB_TT_PROC, "Proc", "to_proc");
+ }
if (argc < 0) {
struct RArray *ary = mrb_ary_ptr(regs[1]);
argv = ary->ptr;
@@ -1301,21 +1305,25 @@ RETRY_TRY_BLOCK:
}
}
else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {
+ mrb_gc_protect(mrb, argv[0]);
argc = mrb_ary_ptr(argv[0])->len;
argv = mrb_ary_ptr(argv[0])->ptr;
}
mrb->c->ci->argc = len;
if (argc < len) {
+ int mlen = m2;
+ if (argc < m1+m2) {
+ if (m1 < argc)
+ mlen = argc - m1;
+ else
+ mlen = 0;
+ }
regs[len+1] = *blk; /* move block */
SET_NIL_VALUE(regs[argc+1]);
if (argv0 != argv) {
- value_move(&regs[1], argv, argc-m2); /* m1 + o */
+ value_move(&regs[1], argv, argc-mlen); /* m1 + o */
}
- if (m2) {
- int mlen = m2;
- if (argc-m2 <= m1) {
- mlen = argc - m1;
- }
+ if (mlen) {
value_move(&regs[len-m2+1], &argv[argc-mlen], mlen);
}
if (r) {
@@ -1349,7 +1357,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_KARG) {
- /* A B C R(A) := kdict[Sym(B)]; if C kdict.rm(Sym(B)) */
+ /* A B C R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */
/* if C == 2; raise unless kdict.empty? */
/* OP_JMP should follow to skip init code */
NEXT;
@@ -1364,7 +1372,7 @@ RETRY_TRY_BLOCK:
i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL);
/* fall through */
CASE(OP_RETURN) {
- /* A return R(A) */
+ /* A B return R(A) (B=normal,in-block return/break) */
if (mrb->exc) {
mrb_callinfo *ci;
int eidx;
@@ -1502,7 +1510,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_TAILCALL) {
- /* A B C return call(R(A),Sym(B),R(A+1),... ,R(A+C-1)) */
+ /* A B C return call(R(A),Syms(B),R(A+1),... ,R(A+C+1)) */
int a = GETARG_A(i);
int n = GETARG_C(i);
struct RProc *m;
@@ -1722,19 +1730,24 @@ RETRY_TRY_BLOCK:
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
{
- mrb_int x, y, z;
+ mrb_value z;
- x = mrb_fixnum(regs[a]);
- y = mrb_fixnum(regs[a+1]);
- z = x * y;
-#ifdef MRB_WORD_BOXING
- z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT);
-#endif
- if (x != 0 && z/x != y) {
- SET_FLT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
- }
- else {
- SET_INT_VALUE(regs[a], z);
+ z = mrb_fixnum_mul(mrb, regs[a], regs[a+1]);
+
+ switch (mrb_type(z)) {
+ case MRB_TT_FIXNUM:
+ {
+ SET_INT_VALUE(regs[a], mrb_fixnum(z));
+ }
+ break;
+ case MRB_TT_FLOAT:
+ {
+ SET_FLT_VALUE(mrb, regs[a], mrb_float(z));
+ }
+ break;
+ default:
+ /* cannot happen */
+ break;
}
}
break;
@@ -1932,7 +1945,7 @@ RETRY_TRY_BLOCK:
} while(0)
CASE(OP_EQ) {
- /* A B C R(A) := R(A)<R(A+1) (Syms[B]=:==,C=1)*/
+ /* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/
int a = GETARG_A(i);
if (mrb_obj_eq(mrb, regs[a], regs[a+1])) {
SET_TRUE_VALUE(regs[a]);
@@ -1958,14 +1971,14 @@ RETRY_TRY_BLOCK:
}
CASE(OP_GT) {
- /* A B C R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1)*/
+ /* A B C R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1)*/
int a = GETARG_A(i);
OP_CMP(>);
NEXT;
}
CASE(OP_GE) {
- /* A B C R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)*/
+ /* A B C R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)*/
int a = GETARG_A(i);
OP_CMP(>=);
NEXT;
@@ -2111,7 +2124,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_CLASS) {
- /* A B R(A) := newclass(R(A),Sym(B),R(A+1)) */
+ /* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */
struct RClass *c = 0;
int a = GETARG_A(i);
mrb_value base, super;
@@ -2129,7 +2142,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_MODULE) {
- /* A B R(A) := newmodule(R(A),Sym(B)) */
+ /* A B R(A) := newmodule(R(A),Syms(B)) */
struct RClass *c = 0;
int a = GETARG_A(i);
mrb_value base;
@@ -2190,7 +2203,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_METHOD) {
- /* A B R(A).newmethod(Sym(B),R(A+1)) */
+ /* A B R(A).newmethod(Syms(B),R(A+1)) */
int a = GETARG_A(i);
struct RClass *c = mrb_class_ptr(regs[a]);
@@ -2207,7 +2220,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_TCLASS) {
- /* A B R(A) := target_class */
+ /* A R(A) := target_class */
if (!mrb->c->ci->target_class) {
mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
mrb->exc = mrb_obj_ptr(exc);
@@ -2226,7 +2239,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_DEBUG) {
- /* A debug print R(A),R(B),R(C) */
+ /* A B C debug print R(A),R(B),R(C) */
#ifdef ENABLE_DEBUG
mrb->debug_op_hook(mrb, irep, pc, regs);
#else