diff options
| -rw-r--r-- | mrbgems/mruby-bin-mruby/bintest/mruby.rb | 7 | ||||
| -rw-r--r-- | src/dump.c | 17 | ||||
| -rw-r--r-- | src/load.c | 20 |
3 files changed, 41 insertions, 3 deletions
diff --git a/mrbgems/mruby-bin-mruby/bintest/mruby.rb b/mrbgems/mruby-bin-mruby/bintest/mruby.rb index a7fb63fa2..f3c7d8761 100644 --- a/mrbgems/mruby-bin-mruby/bintest/mruby.rb +++ b/mrbgems/mruby-bin-mruby/bintest/mruby.rb @@ -31,6 +31,13 @@ assert '$0 value' do assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp end +assert('float literal') do + script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb') + File.write script.path, 'p [3.21, 2e308.infinite?, -2e308.infinite?]' + system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}" + assert_equal "[3.21, 1, -1]", `#{cmd('mruby')} -b #{bin.path}`.chomp! +end + assert '__END__', '8.6' do script = Tempfile.new('test.rb') diff --git a/src/dump.c b/src/dump.c index 6ce9c4eb9..11eba4e40 100644 --- a/src/dump.c +++ b/src/dump.c @@ -6,6 +6,7 @@ #include <string.h> #include <limits.h> +#include <math.h> #include <mruby/dump.h> #include <mruby/string.h> #include <mruby/irep.h> @@ -90,6 +91,18 @@ write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) return cur - buf; } +#ifndef MRB_WITHOUT_FLOAT +static mrb_value +float_to_str(mrb_state *mrb, mrb_value flt) +{ + mrb_float f = mrb_float(flt); + + if (isinf(f)) { + return f < 0 ? mrb_str_new_lit(mrb, "I") : mrb_str_new_lit(mrb, "i"); + } + return mrb_float_to_str(mrb, flt, MRB_FLOAT_FMT); +} +#endif static size_t get_pool_block_size(mrb_state *mrb, mrb_irep *irep) @@ -116,7 +129,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep) #ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: - str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); + str = float_to_str(mrb, irep->pool[pool_no]); { mrb_int len = RSTRING_LEN(str); mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); @@ -165,7 +178,7 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) #ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ - str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); + str = float_to_str(mrb, irep->pool[pool_no]); break; #endif diff --git a/src/load.c b/src/load.c index 559fff1d4..55e0845f3 100644 --- a/src/load.c +++ b/src/load.c @@ -7,6 +7,7 @@ #include <limits.h> #include <stdlib.h> #include <string.h> +#include <math.h> #include <mruby/dump.h> #include <mruby/irep.h> #include <mruby/proc.h> @@ -40,6 +41,23 @@ offset_crc_body(void) return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc); } +#ifndef MRB_WITHOUT_FLOAT +static double +str_to_double(mrb_state *mrb, mrb_value str) +{ + const char *p = RSTRING_PTR(str); + mrb_int len = RSTRING_LEN(str); + + /* `i`, `inf`, `infinity` */ + if (len > 0 && p[0] == 'i') return INFINITY; + + /* `I`, `-inf`, `-infinity` */ + if (p[0] == 'I' || (len > 1 && p[0] == '-' && p[1] == 'i')) return -INFINITY; + + return mrb_str_to_dbl(mrb, str, TRUE); +} +#endif + static mrb_irep* read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) { @@ -125,7 +143,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag #ifndef MRB_WITHOUT_FLOAT case IREP_TT_FLOAT: - irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE)); + irep->pool[i] = mrb_float_pool(mrb, str_to_double(mrb, s)); break; #endif |
