summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorHiroshi Mimaki <[email protected]>2020-06-05 12:42:56 +0900
committerHiroshi Mimaki <[email protected]>2020-06-05 12:42:56 +0900
commit81d340e0421daf39a8208a0181d6a54e726db134 (patch)
tree18cefdd763a716dbd27c23bfdf98ffa2135f7624 /src
parentf9d113f7647121f8578742a2a9ac256ece365e3f (diff)
parent4e40169ed6d200918e542aa8d8e64634794e1864 (diff)
downloadmruby-81d340e0421daf39a8208a0181d6a54e726db134.tar.gz
mruby-81d340e0421daf39a8208a0181d6a54e726db134.zip
Merge master.
Diffstat (limited to 'src')
-rw-r--r--src/array.c11
-rw-r--r--src/class.c35
-rw-r--r--src/codedump.c4
-rw-r--r--src/dump.c68
-rw-r--r--src/etc.c17
-rw-r--r--src/fmt_fp.c119
-rw-r--r--src/hash.c4
-rw-r--r--src/kernel.c4
-rw-r--r--src/load.c20
-rw-r--r--src/numeric.c32
-rw-r--r--src/object.c16
-rw-r--r--src/string.c2
-rw-r--r--src/vm.c40
13 files changed, 211 insertions, 161 deletions
diff --git a/src/array.c b/src/array.c
index 8547cfff4..ad0d5b8db 100644
--- a/src/array.c
+++ b/src/array.c
@@ -732,6 +732,10 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
argv = ARY_PTR(r);
}
}
+ else if (mrb_undef_p(rpl)) {
+ argc = 0;
+ argv = NULL;
+ }
else {
argc = 1;
argv = &rpl;
@@ -804,6 +808,13 @@ ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len)
return mrb_obj_value(b);
}
+mrb_value
+mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len)
+{
+ struct RArray *a = mrb_ary_ptr(ary);
+ return ary_subseq(mrb, a, beg, len);
+}
+
static mrb_int
aget_index(mrb_state *mrb, mrb_value index)
{
diff --git a/src/class.c b/src/class.c
index c49f0f474..d30edd41e 100644
--- a/src/class.c
+++ b/src/class.c
@@ -1242,33 +1242,45 @@ mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
return mod;
}
-MRB_API mrb_value
-mrb_singleton_class(mrb_state *mrb, mrb_value v)
+/* returns mrb_class_ptr(mrb_singleton_class()) */
+/* except that it return NULL for immediate values */
+MRB_API struct RClass*
+mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v)
{
struct RBasic *obj;
switch (mrb_type(v)) {
case MRB_TT_FALSE:
if (mrb_nil_p(v))
- return mrb_obj_value(mrb->nil_class);
- return mrb_obj_value(mrb->false_class);
+ return mrb->nil_class;
+ return mrb->false_class;
case MRB_TT_TRUE:
- return mrb_obj_value(mrb->true_class);
+ return mrb->true_class;
case MRB_TT_CPTR:
- return mrb_obj_value(mrb->object_class);
+ return mrb->object_class;
case MRB_TT_SYMBOL:
case MRB_TT_FIXNUM:
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT:
#endif
- mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
- return mrb_nil_value(); /* not reached */
+ return NULL;
default:
break;
}
obj = mrb_basic_ptr(v);
prepare_singleton_class(mrb, obj);
- return mrb_obj_value(obj->c);
+ return obj->c;
+}
+
+MRB_API mrb_value
+mrb_singleton_class(mrb_state *mrb, mrb_value v)
+{
+ struct RClass *c = mrb_singleton_class_ptr(mrb, v);
+
+ if (c == NULL) {
+ mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
+ }
+ return mrb_obj_value(c);
}
MRB_API void
@@ -1716,7 +1728,10 @@ mrb_class_real(struct RClass* cl)
MRB_API const char*
mrb_class_name(mrb_state *mrb, struct RClass* c)
{
- mrb_value name = class_name_str(mrb, c);
+ mrb_value name;
+
+ if (c == NULL) return NULL;
+ name = class_name_str(mrb, c);
return RSTRING_PTR(name);
}
diff --git a/src/codedump.c b/src/codedump.c
index 7faa39360..649be176b 100644
--- a/src/codedump.c
+++ b/src/codedump.c
@@ -130,6 +130,10 @@ codedump(mrb_state *mrb, mrb_irep *irep)
printf("OP_LOADI\tR%d\t-%d\t", a, b);
print_lv_a(mrb, irep, a);
break;
+ CASE(OP_LOADI16, BS):
+ printf("OP_LOADI16\tR%d\t%d\t", a, (int)(int16_t)b);
+ print_lv_a(mrb, irep, a);
+ break;
CASE(OP_LOADI__1, B):
printf("OP_LOADI__1\tR%d\t\t", a);
print_lv_a(mrb, irep, a);
diff --git a/src/dump.c b/src/dump.c
index 183f3b67d..a6bbe68f3 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -13,9 +13,6 @@
#include <mruby/numeric.h>
#include <mruby/debug.h>
-#define FLAG_BYTEORDER_NATIVE 2
-#define FLAG_BYTEORDER_NONATIVE 0
-
#ifndef MRB_WITHOUT_FLOAT
#ifdef MRB_USE_FLOAT
#define MRB_FLOAT_FMT "%.9g"
@@ -709,22 +706,7 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8
uint16_t crc;
uint32_t offset;
- switch (flags & DUMP_ENDIAN_NAT) {
- endian_big:
- case DUMP_ENDIAN_BIG:
- memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident));
- break;
- endian_little:
- case DUMP_ENDIAN_LIL:
- memcpy(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident));
- break;
-
- case DUMP_ENDIAN_NAT:
- if (bigendian_p()) goto endian_big;
- goto endian_little;
- break;
- }
-
+ memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident));
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));
@@ -764,21 +746,6 @@ lv_defined_p(mrb_irep *irep)
return FALSE;
}
-static uint8_t
-dump_flags(uint8_t flags, uint8_t native)
-{
- if (native == FLAG_BYTEORDER_NATIVE) {
- if ((flags & DUMP_ENDIAN_NAT) == 0) {
- return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_NAT;
- }
- return flags;
- }
- if ((flags & DUMP_ENDIAN_NAT) == 0) {
- return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_BIG;
- }
- return flags;
-}
-
static int
dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size)
{
@@ -870,7 +837,7 @@ error_exit:
int
mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size)
{
- return dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), bin, bin_size);
+ return dump_irep(mrb, irep, flags, bin, bin_size);
}
#ifndef MRB_DISABLE_STDIO
@@ -886,7 +853,7 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE* fp)
return MRB_DUMP_INVALID_ARGUMENT;
}
- result = dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), &bin, &bin_size);
+ result = dump_irep(mrb, irep, flags, &bin, &bin_size);
if (result == MRB_DUMP_OK) {
if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) {
result = MRB_DUMP_WRITE_FAULT;
@@ -897,20 +864,6 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE* fp)
return result;
}
-static mrb_bool
-dump_bigendian_p(uint8_t flags)
-{
- switch (flags & DUMP_ENDIAN_NAT) {
- case DUMP_ENDIAN_BIG:
- return TRUE;
- case DUMP_ENDIAN_LIL:
- return FALSE;
- default:
- case DUMP_ENDIAN_NAT:
- return bigendian_p();
- }
-}
-
int
mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname)
{
@@ -921,23 +874,8 @@ mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE *fp, con
if (fp == NULL || initname == NULL || initname[0] == '\0') {
return MRB_DUMP_INVALID_ARGUMENT;
}
- flags = dump_flags(flags, FLAG_BYTEORDER_NATIVE);
result = dump_irep(mrb, irep, flags, &bin, &bin_size);
if (result == MRB_DUMP_OK) {
- if (!dump_bigendian_p(flags)) {
- if (fprintf(fp, "/* dumped in little endian order.\n"
- " use `mrbc -E` option for big endian CPU. */\n") < 0) {
- mrb_free(mrb, bin);
- return MRB_DUMP_WRITE_FAULT;
- }
- }
- else {
- if (fprintf(fp, "/* dumped in big endian order.\n"
- " use `mrbc -e` option for better performance on little endian CPU. */\n") < 0) {
- mrb_free(mrb, bin);
- return MRB_DUMP_WRITE_FAULT;
- }
- }
if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */
mrb_free(mrb, bin);
return MRB_DUMP_WRITE_FAULT;
diff --git a/src/etc.c b/src/etc.c
index 607e82ca1..6e1533e3d 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -140,7 +140,13 @@ mrb_obj_id(mrb_value obj)
}
}
+#if defined(MRB_NAN_BOXING) && defined(MRB_64BIT)
+#define mrb_xxx_boxing_cptr_value mrb_nan_boxing_cptr_value
+#endif
+
#ifdef MRB_WORD_BOXING
+#define mrb_xxx_boxing_cptr_value mrb_word_boxing_cptr_value
+
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value
mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
@@ -164,17 +170,20 @@ mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f)
return mrb_obj_value(nf);
}
#endif /* MRB_WITHOUT_FLOAT */
+#endif /* MRB_WORD_BOXING */
+#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT))
MRB_API mrb_value
-mrb_word_boxing_cptr_value(mrb_state *mrb, void *p)
+mrb_xxx_boxing_cptr_value(mrb_state *mrb, void *p)
{
mrb_value v;
+ struct RCptr *cptr = (struct RCptr*)mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class);
- v.value.p = mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class);
- v.value.vp->p = p;
+ SET_OBJ_VALUE(v, cptr);
+ cptr->p = p;
return v;
}
-#endif /* MRB_WORD_BOXING */
+#endif
#if defined _MSC_VER && _MSC_VER < 1900
diff --git a/src/fmt_fp.c b/src/fmt_fp.c
index b77abe7b5..9ae5dd177 100644
--- a/src/fmt_fp.c
+++ b/src/fmt_fp.c
@@ -37,9 +37,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <mruby.h>
#include <mruby/string.h>
+struct fmt_args;
+
+typedef void output_func(struct fmt_args *f, const char *s, size_t l);
+
struct fmt_args {
mrb_state *mrb;
- mrb_value str;
+ output_func *output;
+ void *opaque;
+};
+
+struct mrb_cstr {
+ char *buf;
+ size_t len;
};
#define MAX(a,b) ((a)>(b) ? (a) : (b))
@@ -54,15 +64,44 @@ struct fmt_args {
#define PAD_POS (1U<<(' '-' '))
#define MARK_POS (1U<<('+'-' '))
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS)
+
+static output_func strcat_value;
+static output_func strcat_cstr;
+
+static void
+strcat_value(struct fmt_args *f, const char *s, size_t l)
+{
+ mrb_value str = *(mrb_value*)f->opaque;
+ mrb_str_cat(f->mrb, str, s, l);
+}
+
+static void
+strcat_cstr(struct fmt_args *f, const char *s, size_t l)
+{
+ struct mrb_cstr *cstr = (struct mrb_cstr*)f->opaque;
+
+ if (l > cstr->len) {
+ mrb_state *mrb = f->mrb;
+
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "string buffer too small");
+ }
+
+ memcpy(cstr->buf, s, l);
+
+ cstr->buf += l;
+ cstr->len -= l;
+}
+
static void
out(struct fmt_args *f, const char *s, size_t l)
{
- mrb_str_cat(f->mrb, f->str, s, l);
+ f->output(f, s, l);
}
#define PAD_SIZE 256
static void
-pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl)
+pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint32_t fl)
{
char pad[PAD_SIZE];
if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
@@ -92,7 +131,7 @@ typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)
#endif
static int
-fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
+fmt_fp(struct fmt_args *f, long double y, ptrdiff_t w, ptrdiff_t p, uint32_t fl, int t)
{
uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion
+ (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion
@@ -117,11 +156,11 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
if (!isfinite(y)) {
const char *ss = (t&32)?"inf":"INF";
if (y!=y) ss=(t&32)?"nan":"NAN";
- pad(f, ' ', 0, 3+pl, fl&~ZERO_PAD);
+ pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
out(f, prefix, pl);
out(f, ss, 3);
- pad(f, ' ', 0, 3+pl, fl^LEFT_ADJ);
- return 3+(int)pl;
+ pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
+ return MAX(w, 3+(int)pl);
}
y = frexp((double)y, &e2) * 2;
@@ -169,14 +208,14 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
else
l = (s-buf) + (ebuf-estr);
- pad(f, ' ', 0, pl+l, fl);
+ pad(f, ' ', w, pl+l, fl);
out(f, prefix, pl);
- pad(f, '0', 0, pl+l, fl^ZERO_PAD);
+ pad(f, '0', w, pl+l, fl^ZERO_PAD);
out(f, buf, s-buf);
pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
out(f, estr, ebuf-estr);
- pad(f, ' ', 0, pl+l, fl^LEFT_ADJ);
- return (int)pl+(int)l;
+ pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+ return MAX(w, (int)pl+(int)l);
}
if (p<0) p=6;
@@ -288,9 +327,9 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
l += ebuf-estr;
}
- pad(f, ' ', 0, pl+l, fl);
+ pad(f, ' ', w, pl+l, fl);
out(f, prefix, pl);
- pad(f, '0', 0, pl+l, fl^ZERO_PAD);
+ pad(f, '0', w, pl+l, fl^ZERO_PAD);
if ((t|32)=='f') {
if (a>r) a=r;
@@ -325,21 +364,33 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
out(f, estr, ebuf-estr);
}
- pad(f, ' ', 0, pl+l, fl^LEFT_ADJ);
+ pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
- return (int)pl+(int)l;
+ return MAX(w, (int)pl+(int)l);
}
static int
fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo)
{
- ptrdiff_t p;
+ ptrdiff_t w, p;
+ uint32_t fl;
if (*fmt != '%') {
return -1;
}
++fmt;
+ /* Read modifier flags */
+ for (fl=0; (unsigned)*fmt-' '<32 && (FLAGMASK&(1U<<(*fmt-' '))); fmt++)
+ fl |= 1U<<(*fmt-' ');
+
+ /* - and 0 flags are mutually exclusive */
+ if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
+
+ for (w = 0; ISDIGIT(*fmt); ++fmt) {
+ w = 10 * w + (*fmt - '0');
+ }
+
if (*fmt == '.') {
++fmt;
for (p = 0; ISDIGIT(*fmt); ++fmt) {
@@ -353,29 +404,49 @@ fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo)
switch (*fmt) {
case 'e': case 'f': case 'g': case 'a':
case 'E': case 'F': case 'G': case 'A':
- return fmt_fp(f, flo, p, 0, *fmt);
+ return fmt_fp(f, flo, w, p, fl, *fmt);
default:
return -1;
}
}
-mrb_value
+MRB_API mrb_value
mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
{
struct fmt_args f;
+ mrb_value str = mrb_str_new_capa(mrb, 24);
f.mrb = mrb;
- f.str = mrb_str_new_capa(mrb, 24);
+ f.output = strcat_value;
+ f.opaque = (void*)&str;
if (fmt_core(&f, fmt, mrb_float(flo)) < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string");
}
- return f.str;
+ return str;
+}
+
+MRB_API int
+mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval)
+{
+ struct fmt_args f;
+ struct mrb_cstr cstr;
+
+ cstr.buf = buf;
+ cstr.len = len - 1; /* reserve NUL terminator */
+ f.mrb = mrb;
+ f.output = strcat_cstr;
+ f.opaque = (void*)&cstr;
+ if (fmt_core(&f, fmt, fval) < 0) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string");
+ }
+ *cstr.buf = '\0';
+ return cstr.buf - buf;
}
#else /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
#include <mruby.h>
#include <stdio.h>
-mrb_value
+MRB_API mrb_value
mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
{
char buf[25];
@@ -383,5 +454,11 @@ mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
snprintf(buf, sizeof(buf), fmt, mrb_float(flo));
return mrb_str_new_cstr(mrb, buf);
}
+
+MRB_API int
+mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval)
+{
+ return snprintf(buf, len, fmt, fval);
+}
#endif /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
#endif
diff --git a/src/hash.c b/src/hash.c
index 8e7f97147..ec79a3def 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -373,7 +373,7 @@ ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
deleted++;
continue;
}
- if (ht_hash_equal(mrb, t, k, key)) {
+ if (ht_hash_equal(mrb, t, key, k)) {
seg->e[i].val = val;
return;
}
@@ -454,7 +454,7 @@ ht_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
return FALSE;
}
if (mrb_undef_p(k)) continue;
- if (ht_hash_equal(mrb, t, k, key)) {
+ if (ht_hash_equal(mrb, t, key, k)) {
if (vp) *vp = seg->e[i].val;
return TRUE;
}
diff --git a/src/kernel.c b/src/kernel.c
index 8bb837eca..ae9617686 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -325,7 +325,7 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
mrb_value clone;
if (mrb_immediate_p(self)) {
- mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %v", self);
+ return self;
}
if (mrb_sclass_p(self)) {
mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
@@ -366,7 +366,7 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
mrb_value dup;
if (mrb_immediate_p(obj)) {
- mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %v", obj);
+ return obj;
}
if (mrb_sclass_p(obj)) {
mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
diff --git a/src/load.c b/src/load.c
index e624c52d5..2a118c922 100644
--- a/src/load.c
+++ b/src/load.c
@@ -19,9 +19,6 @@
# error size_t must be at least 32 bits wide
#endif
-#define FLAG_BYTEORDER_BIG 2
-#define FLAG_BYTEORDER_LIL 4
-#define FLAG_BYTEORDER_NATIVE 8
#define FLAG_SRC_MALLOC 1
#define FLAG_SRC_STATIC 0
@@ -94,8 +91,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) {
return NULL;
}
- if ((flags & FLAG_SRC_MALLOC) == 0 &&
- (flags & FLAG_BYTEORDER_NATIVE)) {
+ if ((flags & FLAG_SRC_MALLOC) == 0) {
irep->iseq = (mrb_code*)src;
src += sizeof(mrb_code) * irep->ilen;
irep->flags |= MRB_ISEQ_NO_FREE;
@@ -464,19 +460,7 @@ read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint16_
return MRB_DUMP_READ_FAULT;
}
- if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) {
- if (bigendian_p())
- *flags |= FLAG_BYTEORDER_NATIVE;
- else
- *flags |= FLAG_BYTEORDER_BIG;
- }
- else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) {
- if (bigendian_p())
- *flags |= FLAG_BYTEORDER_LIL;
- else
- *flags |= FLAG_BYTEORDER_NATIVE;
- }
- else {
+ if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) != 0) {
return MRB_DUMP_INVALID_FILE_HEADER;
}
diff --git a/src/numeric.c b/src/numeric.c
index 6cfd64280..07a2d20a8 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -210,26 +210,30 @@ static mrb_value
flo_to_s(mrb_state *mrb, mrb_value flt)
{
mrb_float f = mrb_float(flt);
+ mrb_value str;
if (isinf(f)) {
- return f < 0 ? mrb_str_new_lit(mrb, "-Infinity")
- : mrb_str_new_lit(mrb, "Infinity");
+ str = f < 0 ? mrb_str_new_lit(mrb, "-Infinity")
+ : mrb_str_new_lit(mrb, "Infinity");
+ goto exit;
}
else if (isnan(f)) {
- return mrb_str_new_lit(mrb, "NaN");
+ str = mrb_str_new_lit(mrb, "NaN");
+ goto exit;
}
else {
char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g";
- mrb_value str = mrb_float_to_str(mrb, flt, fmt);
mrb_int len;
char *begp, *p, *endp;
+ str = mrb_float_to_str(mrb, flt, fmt);
+
insert_dot_zero:
begp = RSTRING_PTR(str);
len = RSTRING_LEN(str);
for (p = begp, endp = p + len; p < endp; ++p) {
if (*p == '.') {
- return str;
+ goto exit;
}
else if (*p == 'e') {
ptrdiff_t e_pos = p - begp;
@@ -237,7 +241,7 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
p = RSTRING_PTR(str) + e_pos;
memmove(p + 2, p, len - e_pos);
memcpy(p, ".0", 2);
- return str;
+ goto exit;
}
}
@@ -247,8 +251,12 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
goto insert_dot_zero;
}
- return str;
+ goto exit;
}
+
+ exit:
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+ return str;
}
/* 15.2.9.3.2 */
@@ -1383,6 +1391,7 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
char buf[MRB_INT_BIT+1];
char *b = buf + sizeof buf;
mrb_int val = mrb_fixnum(x);
+ mrb_value str;
if (base < 2 || 36 < base) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base);
@@ -1403,7 +1412,9 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
} while (val /= base);
}
- return mrb_str_new(mrb, b, buf + sizeof(buf) - b);
+ str = mrb_str_new(mrb, b, buf + sizeof(buf) - b);
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+ return str;
}
/* 15.2.8.3.25 */
@@ -1474,13 +1485,14 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2)
/* 15.2.9.3.6 */
/*
* call-seq:
- * self.f <=> other.f => -1, 0, +1
+ * self.f <=> other.f => -1, 0, +1, or nil
* < => -1
* = => 0
* > => +1
* Comparison---Returns -1, 0, or +1 depending on whether <i>fix</i> is
* less than, equal to, or greater than <i>numeric</i>. This is the
- * basis for the tests in <code>Comparable</code>.
+ * basis for the tests in <code>Comparable</code>. When the operands are
+ * not comparable, it returns nil instead of raising an exception.
*/
static mrb_value
integral_cmp(mrb_state *mrb, mrb_value self)
diff --git a/src/object.c b/src/object.c
index 33d570331..8de42a641 100644
--- a/src/object.c
+++ b/src/object.c
@@ -83,13 +83,17 @@ mrb_true(mrb_state *mrb, mrb_value obj)
static mrb_value
nil_to_s(mrb_state *mrb, mrb_value obj)
{
- return mrb_str_new_frozen(mrb, 0, 0);
+ mrb_value str = mrb_str_new_frozen(mrb, 0, 0);
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+ return str;
}
static mrb_value
nil_inspect(mrb_state *mrb, mrb_value obj)
{
- return mrb_str_new_lit_frozen(mrb, "nil");
+ mrb_value str = mrb_str_new_lit_frozen(mrb, "nil");
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+ return str;
}
/***********************************************************************
@@ -150,7 +154,9 @@ true_xor(mrb_state *mrb, mrb_value obj)
static mrb_value
true_to_s(mrb_state *mrb, mrb_value obj)
{
- return mrb_str_new_lit_frozen(mrb, "true");
+ mrb_value str = mrb_str_new_lit_frozen(mrb, "true");
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+ return str;
}
/* 15.2.5.3.4 */
@@ -257,7 +263,9 @@ false_or(mrb_state *mrb, mrb_value obj)
static mrb_value
false_to_s(mrb_state *mrb, mrb_value obj)
{
- return mrb_str_new_lit_frozen(mrb, "false");
+ mrb_value str = mrb_str_new_lit_frozen(mrb, "false");
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+ return str;
}
void
diff --git a/src/string.c b/src/string.c
index 458c511dc..44e3c9069 100644
--- a/src/string.c
+++ b/src/string.c
@@ -2759,7 +2759,7 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
MRB_API mrb_value
mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr)
{
- return mrb_str_cat(mrb, str, ptr, strlen(ptr));
+ return mrb_str_cat(mrb, str, ptr, ptr ? strlen(ptr) : 0);
}
MRB_API mrb_value
diff --git a/src/vm.c b/src/vm.c
index d7826230e..a280026f8 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -324,6 +324,7 @@ cipop(mrb_state *mrb)
}
void mrb_exc_set(mrb_state *mrb, mrb_value exc);
+static mrb_value mrb_run(mrb_state *mrb, struct RProc* proc, mrb_value self);
static void
ecall(mrb_state *mrb)
@@ -335,10 +336,12 @@ ecall(mrb_state *mrb)
struct REnv *env;
ptrdiff_t cioff;
int ai = mrb_gc_arena_save(mrb);
- uint16_t i = --c->eidx;
+ uint16_t i;
int nregs;
- if (i<0) return;
+ if (c->eidx == 0) return;
+ i = --c->eidx;
+
/* restrict total call depth of ecall() */
if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) {
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
@@ -624,7 +627,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
ci->argc--;
}
else { /* variable length arguments */
- mrb_ary_shift(mrb, regs[0]);
+ regs[0] = mrb_ary_subseq(mrb, regs[0], 1, RARRAY_LEN(regs[0]) - 1);
}
if (MRB_METHOD_CFUNC_P(m)) {
@@ -648,8 +651,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
}
ci = mrb->c->ci;
if (ci->acc == CI_ACC_DIRECT) {
- ci->target_class = c;
- return mrb_yield_cont(mrb, blk, self, 1, &self);
+ return mrb_yield_with_class(mrb, blk, 1, &self, self, c);
}
ci->target_class = c;
p = mrb_proc_ptr(blk);
@@ -724,26 +726,11 @@ mrb_value
mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
{
mrb_value a, b;
- mrb_value cv;
- struct RClass *c;
if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented");
}
- switch (mrb_type(self)) {
- case MRB_TT_SYMBOL:
- case MRB_TT_FIXNUM:
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
-#endif
- c = 0;
- break;
- default:
- cv = mrb_singleton_class(mrb, self);
- c = mrb_class_ptr(cv);
- break;
- }
- return eval_under(mrb, self, b, c);
+ return eval_under(mrb, self, b, mrb_singleton_class_ptr(mrb, self));
}
MRB_API mrb_value
@@ -1062,6 +1049,11 @@ RETRY_TRY_BLOCK:
NEXT;
}
+ CASE(OP_LOADI16, BS) {
+ SET_INT_VALUE(regs[a], (mrb_int)(int16_t)b);
+ NEXT;
+ }
+
CASE(OP_LOADSYM, BB) {
SET_SYM_VALUE(regs[a], syms[b]);
NEXT;
@@ -1099,13 +1091,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_GETSV, BB) {
- mrb_value val = mrb_vm_special_get(mrb, b);
+ mrb_value val = mrb_vm_special_get(mrb, syms[b]);
regs[a] = val;
NEXT;
}
CASE(OP_SETSV, BB) {
- mrb_vm_special_set(mrb, b, regs[a]);
+ mrb_vm_special_set(mrb, syms[b], regs[a]);
NEXT;
}
@@ -2824,7 +2816,7 @@ RETRY_TRY_BLOCK:
MRB_END_EXC(&c_jmp);
}
-MRB_API mrb_value
+static mrb_value
mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
{
if (mrb->c->ci->argc < 0) {