esruby 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/esruby/build.rb +7 -4
- data/resources/build_config.eruby +1 -0
- data/resources/cpp/main.cpp +14 -0
- data/resources/mruby/doc/guides/mrbgems.md +5 -0
- data/resources/mruby/include/mrbconf.h +3 -5
- data/resources/mruby/include/mruby/proc.h +2 -2
- data/resources/mruby/include/mruby.h +11 -4
- data/resources/mruby/lib/mruby/build/load_gems.rb +5 -3
- data/resources/mruby/lib/mruby/build.rb +23 -0
- data/resources/mruby/lib/mruby/gem.rb +12 -13
- data/resources/mruby/mrbgems/default.gembox +6 -0
- data/resources/mruby/mrbgems/mruby-compiler/core/codegen.c +7 -1
- data/resources/mruby/mrbgems/mruby-compiler/core/parse.y +31 -36
- data/resources/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +33 -10
- data/resources/mruby/mrbgems/mruby-enum-ext/test/enum.rb +6 -0
- data/resources/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb +1 -1
- data/resources/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +32 -17
- data/resources/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +10 -0
- data/resources/mruby/mrbgems/mruby-fiber/src/fiber.c +3 -2
- data/resources/mruby/mrbgems/mruby-io/mrblib/io.rb +3 -2
- data/resources/mruby/mrbgems/mruby-io/src/file.c +15 -0
- data/resources/mruby/mrbgems/mruby-io/src/io.c +16 -8
- data/resources/mruby/mrbgems/mruby-io/test/file.rb +17 -1
- data/resources/mruby/mrbgems/mruby-io/test/io.rb +4 -0
- data/resources/mruby/mrbgems/mruby-pack/src/pack.c +16 -6
- data/resources/mruby/mrbgems/mruby-socket/mrbgem.rake +2 -2
- data/resources/mruby/mrbgems/mruby-socket/test/sockettest.c +42 -6
- data/resources/mruby/mrbgems/mruby-test/init_mrbtest.c +1 -0
- data/resources/mruby/mrbgems/mruby-test/mrbgem.rake +1 -0
- data/resources/mruby/mrbgems/mruby-time/src/time.c +22 -3
- data/resources/mruby/mrbgems/mruby-time/test/time.rb +4 -0
- data/resources/mruby/mrblib/array.rb +8 -9
- data/resources/mruby/mrblib/enum.rb +1 -1
- data/resources/mruby/src/array.c +1 -1
- data/resources/mruby/src/class.c +8 -2
- data/resources/mruby/src/error.c +2 -1
- data/resources/mruby/src/gc.c +1 -1
- data/resources/mruby/src/object.c +2 -2
- data/resources/mruby/src/string.c +8 -8
- data/resources/mruby/src/variable.c +41 -7
- data/resources/mruby/src/vm.c +5 -4
- data/resources/mruby/tasks/toolchains/visualcpp.rake +10 -9
- data/resources/mruby/test/t/string.rb +2 -1
- data/resources/project_template/config.rb +5 -0
- data/resources/rb/append.rb +3 -0
- metadata +3 -4
- data/resources/cpp/esruby.cpp +0 -51
- data/resources/cpp/esruby.hpp +0 -38
- data/resources/js/esruby.js +0 -17
|
@@ -93,8 +93,9 @@ class IO
|
|
|
93
93
|
if path[0] == "|"
|
|
94
94
|
io = IO.popen(path[1..-1], (opt[:mode] || "r"))
|
|
95
95
|
else
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
mode = opt[:mode] || "r"
|
|
97
|
+
fd = IO.sysopen(path, mode)
|
|
98
|
+
io = IO.open(fd, mode)
|
|
98
99
|
end
|
|
99
100
|
io.seek(offset) if offset > 0
|
|
100
101
|
str = io.read(length)
|
|
@@ -332,6 +332,20 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass)
|
|
|
332
332
|
#endif
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
+
static mrb_value
|
|
336
|
+
mrb_file_mtime(mrb_state *mrb, mrb_value self)
|
|
337
|
+
{
|
|
338
|
+
mrb_value obj;
|
|
339
|
+
struct stat st;
|
|
340
|
+
int fd;
|
|
341
|
+
|
|
342
|
+
obj = mrb_obj_value(mrb_class_get(mrb, "Time"));
|
|
343
|
+
fd = (int)mrb_fixnum(mrb_io_fileno(mrb, self));
|
|
344
|
+
if (fstat(fd, &st) == -1)
|
|
345
|
+
return mrb_false_value();
|
|
346
|
+
return mrb_funcall(mrb, obj, "at", 1, mrb_float_value(mrb, st.st_mtime));
|
|
347
|
+
}
|
|
348
|
+
|
|
335
349
|
mrb_value
|
|
336
350
|
mrb_file_flock(mrb_state *mrb, mrb_value self)
|
|
337
351
|
{
|
|
@@ -471,6 +485,7 @@ mrb_init_file(mrb_state *mrb)
|
|
|
471
485
|
mrb_define_class_method(mrb, file, "_gethome", mrb_file__gethome, MRB_ARGS_OPT(1));
|
|
472
486
|
|
|
473
487
|
mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1));
|
|
488
|
+
mrb_define_method(mrb, file, "mtime", mrb_file_mtime, MRB_ARGS_NONE());
|
|
474
489
|
|
|
475
490
|
cnst = mrb_define_module_under(mrb, file, "Constants");
|
|
476
491
|
mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH));
|
|
@@ -180,7 +180,7 @@ mrb_io_flags_to_modenum(mrb_state *mrb, int flags)
|
|
|
180
180
|
return modenum;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
void
|
|
183
|
+
static void
|
|
184
184
|
mrb_fd_cloexec(mrb_state *mrb, int fd)
|
|
185
185
|
{
|
|
186
186
|
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
|
|
@@ -188,7 +188,8 @@ mrb_fd_cloexec(mrb_state *mrb, int fd)
|
|
|
188
188
|
|
|
189
189
|
flags = fcntl(fd, F_GETFD);
|
|
190
190
|
if (flags == -1) {
|
|
191
|
-
|
|
191
|
+
mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%S, F_GETFD) failed: %S",
|
|
192
|
+
mrb_fixnum_value(fd), mrb_fixnum_value(errno));
|
|
192
193
|
}
|
|
193
194
|
if (fd <= 2) {
|
|
194
195
|
flags2 = flags & ~FD_CLOEXEC; /* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */
|
|
@@ -198,7 +199,8 @@ mrb_fd_cloexec(mrb_state *mrb, int fd)
|
|
|
198
199
|
}
|
|
199
200
|
if (flags != flags2) {
|
|
200
201
|
if (fcntl(fd, F_SETFD, flags2) == -1) {
|
|
201
|
-
|
|
202
|
+
mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%S, F_SETFD, %S) failed: %S",
|
|
203
|
+
mrb_fixnum_value(fd), mrb_fixnum_value(flags2), mrb_fixnum_value(errno));
|
|
202
204
|
}
|
|
203
205
|
}
|
|
204
206
|
#endif
|
|
@@ -577,11 +579,17 @@ mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
|
|
|
577
579
|
if (failed) {
|
|
578
580
|
mrb_sys_fail(mrb, 0);
|
|
579
581
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
582
|
+
mrb_fd_cloexec(mrb, fptr_copy->fd);
|
|
583
|
+
|
|
584
|
+
if (fptr_orig->fd2 != -1) {
|
|
585
|
+
fptr_copy->fd2 = mrb_dup(mrb, fptr_orig->fd2, &failed);
|
|
586
|
+
if (failed) {
|
|
587
|
+
close(fptr_copy->fd);
|
|
588
|
+
mrb_sys_fail(mrb, 0);
|
|
589
|
+
}
|
|
590
|
+
mrb_fd_cloexec(mrb, fptr_copy->fd2);
|
|
584
591
|
}
|
|
592
|
+
|
|
585
593
|
fptr_copy->pid = fptr_orig->pid;
|
|
586
594
|
fptr_copy->readable = fptr_orig->readable;
|
|
587
595
|
fptr_copy->writable = fptr_orig->writable;
|
|
@@ -676,7 +684,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
|
|
|
676
684
|
io_set_process_status(mrb, pid, status);
|
|
677
685
|
}
|
|
678
686
|
#else
|
|
679
|
-
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, fptr->pid);
|
|
687
|
+
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, fptr->pid);
|
|
680
688
|
DWORD status;
|
|
681
689
|
if (WaitForSingleObject(h, INFINITE) && GetExitCodeProcess(h, &status))
|
|
682
690
|
if (!quiet)
|
|
@@ -54,7 +54,7 @@ assert('File.extname') do
|
|
|
54
54
|
assert_equal '', File.extname('.foo')
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
assert('
|
|
57
|
+
assert('File#flock') do
|
|
58
58
|
f = File.open $mrbtest_io_rfname
|
|
59
59
|
begin
|
|
60
60
|
assert_equal(f.flock(File::LOCK_SH), 0)
|
|
@@ -68,6 +68,22 @@ assert('IO#flock') do
|
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
assert('File#mtime') do
|
|
72
|
+
unless Object.const_defined?(:Time)
|
|
73
|
+
skip "File#mtime require Time"
|
|
74
|
+
end
|
|
75
|
+
begin
|
|
76
|
+
now = Time.now.to_i
|
|
77
|
+
mt = 0
|
|
78
|
+
File.open('mtime-test', 'w') do |f|
|
|
79
|
+
mt = f.mtime.to_i
|
|
80
|
+
end
|
|
81
|
+
assert_equal true, mt >= now
|
|
82
|
+
ensure
|
|
83
|
+
File.delete('mtime-test')
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
71
87
|
assert('File.join') do
|
|
72
88
|
assert_equal "", File.join()
|
|
73
89
|
assert_equal "a", File.join("a")
|
|
@@ -216,6 +216,10 @@ assert('IO#dup for readable') do
|
|
|
216
216
|
dup = io.dup
|
|
217
217
|
assert_true io != dup
|
|
218
218
|
assert_true io.fileno != dup.fileno
|
|
219
|
+
begin
|
|
220
|
+
assert_true dup.close_on_exec?
|
|
221
|
+
rescue NotImplementedError
|
|
222
|
+
end
|
|
219
223
|
assert_equal 'm', dup.sysread(1)
|
|
220
224
|
assert_equal 'r', io.sysread(1)
|
|
221
225
|
assert_equal 'u', dup.sysread(1)
|
|
@@ -107,6 +107,9 @@ static mrb_value
|
|
|
107
107
|
str_len_ensure(mrb_state *mrb, mrb_value str, mrb_int len)
|
|
108
108
|
{
|
|
109
109
|
mrb_int n = RSTRING_LEN(str);
|
|
110
|
+
if (len < 0) {
|
|
111
|
+
mrb_raise(mrb, E_RANGE_ERROR, "negative (or overflowed) integer");
|
|
112
|
+
}
|
|
110
113
|
if (len > n) {
|
|
111
114
|
do {
|
|
112
115
|
n *= 2;
|
|
@@ -515,7 +518,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp)
|
|
|
515
518
|
c = *p++ & 0xff;
|
|
516
519
|
if ((c & 0xc0) != 0x80) {
|
|
517
520
|
*lenp -= n + 1;
|
|
518
|
-
|
|
521
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
|
|
519
522
|
}
|
|
520
523
|
else {
|
|
521
524
|
c &= 0x3f;
|
|
@@ -525,7 +528,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp)
|
|
|
525
528
|
}
|
|
526
529
|
n = *lenp - 1;
|
|
527
530
|
if (uv < utf8_limits[n]) {
|
|
528
|
-
|
|
531
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "redundant UTF-8 sequence");
|
|
529
532
|
}
|
|
530
533
|
return uv;
|
|
531
534
|
}
|
|
@@ -726,7 +729,7 @@ pack_m(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, u
|
|
|
726
729
|
count -= count % 3;
|
|
727
730
|
}
|
|
728
731
|
|
|
729
|
-
dstlen = srclen / 3 * 4;
|
|
732
|
+
dstlen = (srclen+2) / 3 * 4;
|
|
730
733
|
if (count > 0) {
|
|
731
734
|
dstlen += (srclen / count) + ((srclen % count) == 0 ? 0 : 1);
|
|
732
735
|
}
|
|
@@ -803,7 +806,7 @@ unpack_m(mrb_state *mrb, const void *src, int slen, mrb_value ary, unsigned int
|
|
|
803
806
|
ch[i] = 0;
|
|
804
807
|
padding++;
|
|
805
808
|
}
|
|
806
|
-
} while (ch[i] == PACK_BASE64_IGNORE);
|
|
809
|
+
} while (c >= sizeof(base64_dec_tab) || ch[i] == PACK_BASE64_IGNORE);
|
|
807
810
|
}
|
|
808
811
|
|
|
809
812
|
l = (ch[0] << 18) + (ch[1] << 12) + (ch[2] << 6) + ch[3];
|
|
@@ -833,16 +836,17 @@ pack_x(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, u
|
|
|
833
836
|
{
|
|
834
837
|
long i;
|
|
835
838
|
|
|
839
|
+
if (count < 0) return 0;
|
|
836
840
|
dst = str_len_ensure(mrb, dst, didx + count);
|
|
837
841
|
for (i = 0; i < count; i++) {
|
|
838
|
-
RSTRING_PTR(dst)[didx] = '\0';
|
|
842
|
+
RSTRING_PTR(dst)[didx + i] = '\0';
|
|
839
843
|
}
|
|
840
844
|
return count;
|
|
841
845
|
}
|
|
842
|
-
|
|
843
846
|
static int
|
|
844
847
|
unpack_x(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags)
|
|
845
848
|
{
|
|
849
|
+
if (count < 0) return slen;
|
|
846
850
|
if (slen < count) {
|
|
847
851
|
mrb_raise(mrb, E_ARGUMENT_ERROR, "x outside of string");
|
|
848
852
|
}
|
|
@@ -1050,6 +1054,9 @@ alias:
|
|
|
1050
1054
|
count = ch - '0';
|
|
1051
1055
|
while (tmpl->idx < tlen && isdigit(tptr[tmpl->idx])) {
|
|
1052
1056
|
count = count * 10 + (tptr[tmpl->idx++] - '0');
|
|
1057
|
+
if (count < 0) {
|
|
1058
|
+
mrb_raisef(mrb, E_RUNTIME_ERROR, "too big template length");
|
|
1059
|
+
}
|
|
1053
1060
|
}
|
|
1054
1061
|
continue; /* special case */
|
|
1055
1062
|
} else if (ch == '*') {
|
|
@@ -1171,6 +1178,9 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
|
|
|
1171
1178
|
count--;
|
|
1172
1179
|
}
|
|
1173
1180
|
}
|
|
1181
|
+
if (ridx < 0) {
|
|
1182
|
+
mrb_raise(mrb, E_RANGE_ERROR, "negative (or overflowed) template size");
|
|
1183
|
+
}
|
|
1174
1184
|
}
|
|
1175
1185
|
|
|
1176
1186
|
mrb_str_resize(mrb, result, ridx);
|
|
@@ -11,7 +11,7 @@ MRuby::Gem::Specification.new('mruby-socket') do |spec|
|
|
|
11
11
|
spec.linker.libraries << "ws2_32"
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
spec.add_dependency('mruby-io')
|
|
15
|
-
spec.add_dependency('mruby-pack')
|
|
14
|
+
spec.add_dependency('mruby-io', :core => 'mruby-io')
|
|
15
|
+
spec.add_dependency('mruby-pack', :core => 'mruby-pack')
|
|
16
16
|
# spec.add_dependency('mruby-mtest')
|
|
17
17
|
end
|
|
@@ -2,18 +2,54 @@
|
|
|
2
2
|
#include <stdlib.h>
|
|
3
3
|
|
|
4
4
|
#include "mruby.h"
|
|
5
|
+
#include "mruby/error.h"
|
|
6
|
+
|
|
7
|
+
#if defined(_WIN32) || defined(_WIN64)
|
|
8
|
+
|
|
9
|
+
#include <io.h>
|
|
10
|
+
|
|
11
|
+
#ifdef _MSC_VER
|
|
12
|
+
|
|
13
|
+
#include <fcntl.h>
|
|
14
|
+
#include <sys/stat.h>
|
|
15
|
+
#define close _close
|
|
16
|
+
#define unlink _unlink
|
|
17
|
+
|
|
18
|
+
static int
|
|
19
|
+
mkstemp(char *p)
|
|
20
|
+
{
|
|
21
|
+
int fd;
|
|
22
|
+
char* fname = _mktemp(p);
|
|
23
|
+
if (fname == NULL)
|
|
24
|
+
return -1;
|
|
25
|
+
fd = open(fname, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
|
|
26
|
+
if (fd >= 0)
|
|
27
|
+
return fd;
|
|
28
|
+
return -1;
|
|
29
|
+
}
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
#else
|
|
33
|
+
|
|
34
|
+
#include <unistd.h>
|
|
5
35
|
|
|
6
|
-
#ifdef _WIN32
|
|
7
|
-
#define tempnam _tempnam
|
|
8
36
|
#endif
|
|
9
37
|
|
|
10
38
|
mrb_value
|
|
11
39
|
mrb_sockettest_tmppath(mrb_state *mrb, mrb_value klass)
|
|
12
40
|
{
|
|
13
|
-
char
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
41
|
+
char name[] = "mruby-socket.XXXXXXXX";
|
|
42
|
+
int fd = mkstemp(name);
|
|
43
|
+
if (fd == -1) {
|
|
44
|
+
mrb_sys_fail(mrb, 0);
|
|
45
|
+
}
|
|
46
|
+
if (close(fd) == -1) {
|
|
47
|
+
mrb_sys_fail(mrb, 0);
|
|
48
|
+
}
|
|
49
|
+
if (unlink(name) == -1) {
|
|
50
|
+
mrb_sys_fail(mrb, 0);
|
|
51
|
+
}
|
|
52
|
+
return mrb_str_new_cstr(mrb, name);
|
|
17
53
|
}
|
|
18
54
|
|
|
19
55
|
mrb_value
|
|
@@ -101,6 +101,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
|
|
|
101
101
|
end
|
|
102
102
|
f.puts %Q[ if (mrb2->exc) {]
|
|
103
103
|
f.puts %Q[ mrb_print_error(mrb2);]
|
|
104
|
+
f.puts %Q[ mrb_close(mrb2);]
|
|
104
105
|
f.puts %Q[ exit(EXIT_FAILURE);]
|
|
105
106
|
f.puts %Q[ }]
|
|
106
107
|
f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));]
|
|
@@ -67,6 +67,11 @@ double round(double x) {
|
|
|
67
67
|
/* define following macro to use probably faster timegm() on the platform */
|
|
68
68
|
/* #define USE_SYSTEM_TIMEGM */
|
|
69
69
|
|
|
70
|
+
/* time_t */
|
|
71
|
+
/* If your platform supports time_t as uint (e.g. uint32_t, uint64_t), */
|
|
72
|
+
/* uncomment following macro. */
|
|
73
|
+
/* #define MRB_TIME_T_UINT */
|
|
74
|
+
|
|
70
75
|
/** end of Time class configuration */
|
|
71
76
|
|
|
72
77
|
#ifndef NO_GETTIMEOFDAY
|
|
@@ -138,8 +143,14 @@ timegm(struct tm *tm)
|
|
|
138
143
|
int i;
|
|
139
144
|
unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+1900)];
|
|
140
145
|
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
static const int epoch_year = 70;
|
|
147
|
+
if(tm->tm_year >= epoch_year) {
|
|
148
|
+
for (i = epoch_year; i < tm->tm_year; ++i)
|
|
149
|
+
r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60;
|
|
150
|
+
} else {
|
|
151
|
+
for (i = tm->tm_year; i < epoch_year; ++i)
|
|
152
|
+
r -= is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60;
|
|
153
|
+
}
|
|
143
154
|
for (i = 0; i < tm->tm_mon; ++i)
|
|
144
155
|
r += nday[i] * 24 * 60 * 60;
|
|
145
156
|
r += (tm->tm_mday - 1) * 24 * 60 * 60;
|
|
@@ -234,13 +245,21 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone)
|
|
|
234
245
|
|
|
235
246
|
mrb_check_num_exact(mrb, (mrb_float)sec);
|
|
236
247
|
mrb_check_num_exact(mrb, (mrb_float)usec);
|
|
237
|
-
|
|
248
|
+
#ifndef MRB_TIME_T_UINT
|
|
238
249
|
if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) {
|
|
239
250
|
goto out_of_range;
|
|
240
251
|
}
|
|
241
252
|
if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) {
|
|
242
253
|
goto out_of_range;
|
|
243
254
|
}
|
|
255
|
+
#else
|
|
256
|
+
if (sizeof(time_t) == 4 && (sec > (double)UINT32_MAX || (double)0 > sec)) {
|
|
257
|
+
goto out_of_range;
|
|
258
|
+
}
|
|
259
|
+
if (sizeof(time_t) == 8 && (sec > (double)UINT64_MAX || (double)0 > sec)) {
|
|
260
|
+
goto out_of_range;
|
|
261
|
+
}
|
|
262
|
+
#endif
|
|
244
263
|
tsec = (time_t)sec;
|
|
245
264
|
if ((sec > 0 && tsec < 0) || (sec < 0 && (double)tsec > sec)) {
|
|
246
265
|
out_of_range:
|
|
@@ -200,28 +200,27 @@ class Array
|
|
|
200
200
|
|
|
201
201
|
##
|
|
202
202
|
# Quick sort
|
|
203
|
-
# a : the array to sort
|
|
204
203
|
# left : the beginning of sort region
|
|
205
204
|
# right : the end of sort region
|
|
206
|
-
def __sort_sub__(
|
|
205
|
+
def __sort_sub__(left, right, &block)
|
|
207
206
|
if left < right
|
|
208
207
|
i = left
|
|
209
208
|
j = right
|
|
210
|
-
pivot =
|
|
209
|
+
pivot = self[i + (j - i) / 2]
|
|
211
210
|
while true
|
|
212
|
-
while ((block)? block.call(
|
|
211
|
+
while ((block)? block.call(self[i], pivot): (self[i] <=> pivot)) < 0
|
|
213
212
|
i += 1
|
|
214
213
|
end
|
|
215
|
-
while ((block)? block.call(pivot,
|
|
214
|
+
while ((block)? block.call(pivot, self[j]): (pivot <=> self[j])) < 0
|
|
216
215
|
j -= 1
|
|
217
216
|
end
|
|
218
217
|
break if (i >= j)
|
|
219
|
-
tmp =
|
|
218
|
+
tmp = self[i]; self[i] = self[j]; self[j] = tmp;
|
|
220
219
|
i += 1
|
|
221
220
|
j -= 1
|
|
222
221
|
end
|
|
223
|
-
__sort_sub__(
|
|
224
|
-
__sort_sub__(
|
|
222
|
+
__sort_sub__(left, i-1, &block)
|
|
223
|
+
__sort_sub__(j+1, right, &block)
|
|
225
224
|
end
|
|
226
225
|
end
|
|
227
226
|
# private :__sort_sub__
|
|
@@ -232,7 +231,7 @@ class Array
|
|
|
232
231
|
def sort!(&block)
|
|
233
232
|
size = self.size
|
|
234
233
|
if size > 1
|
|
235
|
-
__sort_sub__(
|
|
234
|
+
__sort_sub__(0, size - 1, &block)
|
|
236
235
|
end
|
|
237
236
|
self
|
|
238
237
|
end
|
data/resources/mruby/src/array.c
CHANGED
|
@@ -256,7 +256,6 @@ mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len)
|
|
|
256
256
|
ary_modify(mrb, a);
|
|
257
257
|
old_len = RARRAY_LEN(ary);
|
|
258
258
|
if (old_len != new_len) {
|
|
259
|
-
ARY_SET_LEN(a, new_len);
|
|
260
259
|
if (new_len < old_len) {
|
|
261
260
|
ary_shrink_capa(mrb, a);
|
|
262
261
|
}
|
|
@@ -264,6 +263,7 @@ mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len)
|
|
|
264
263
|
ary_expand_capa(mrb, a, new_len);
|
|
265
264
|
ary_fill_with_nil(ARY_PTR(a) + old_len, new_len - old_len);
|
|
266
265
|
}
|
|
266
|
+
ARY_SET_LEN(a, new_len);
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
return ary;
|
data/resources/mruby/src/class.c
CHANGED
|
@@ -593,7 +593,7 @@ mrb_get_argv(mrb_state *mrb)
|
|
|
593
593
|
n: Symbol [mrb_sym]
|
|
594
594
|
d: Data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified
|
|
595
595
|
I: Inline struct [void*]
|
|
596
|
-
&: Block [mrb_value]
|
|
596
|
+
&: Block [mrb_value] &! raises exception if no block given
|
|
597
597
|
*: rest argument [mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
|
|
598
598
|
|: optional Following arguments are optional
|
|
599
599
|
?: optional given [mrb_bool] true if preceding argument (optional) is given
|
|
@@ -937,6 +937,12 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
|
|
937
937
|
else {
|
|
938
938
|
bp = mrb->c->stack + mrb->c->ci->argc + 1;
|
|
939
939
|
}
|
|
940
|
+
if (*format == '!') {
|
|
941
|
+
format ++;
|
|
942
|
+
if (mrb_nil_p(*bp)) {
|
|
943
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
|
|
944
|
+
}
|
|
945
|
+
}
|
|
940
946
|
*p = *bp;
|
|
941
947
|
}
|
|
942
948
|
break;
|
|
@@ -1744,7 +1750,7 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
|
|
|
1744
1750
|
return mrb_class_find_path(mrb, c);
|
|
1745
1751
|
}
|
|
1746
1752
|
else if (mrb_symbol_p(path)) {
|
|
1747
|
-
/*
|
|
1753
|
+
/* toplevel class/module */
|
|
1748
1754
|
const char *str;
|
|
1749
1755
|
mrb_int len;
|
|
1750
1756
|
|
data/resources/mruby/src/error.c
CHANGED
|
@@ -229,7 +229,8 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc)
|
|
|
229
229
|
}
|
|
230
230
|
else {
|
|
231
231
|
mrb->exc = mrb_obj_ptr(exc);
|
|
232
|
-
if (
|
|
232
|
+
if (mrb->gc.arena_idx > 0 &&
|
|
233
|
+
(struct RBasic*)mrb->exc == mrb->gc.arena[mrb->gc.arena_idx-1]) {
|
|
233
234
|
mrb->gc.arena_idx--;
|
|
234
235
|
}
|
|
235
236
|
if (!mrb->gc.out_of_memory) {
|
data/resources/mruby/src/gc.c
CHANGED
|
@@ -658,7 +658,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
|
|
|
658
658
|
struct REnv *e = (struct REnv*)obj;
|
|
659
659
|
mrb_int i, len;
|
|
660
660
|
|
|
661
|
-
if (MRB_ENV_STACK_SHARED_P(e) && e->cxt->fib) {
|
|
661
|
+
if (MRB_ENV_STACK_SHARED_P(e) && e->cxt && e->cxt->fib) {
|
|
662
662
|
mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib);
|
|
663
663
|
}
|
|
664
664
|
len = MRB_ENV_STACK_LEN(e);
|
|
@@ -569,8 +569,8 @@ arg_error:
|
|
|
569
569
|
mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
|
|
570
570
|
}
|
|
571
571
|
tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
|
|
572
|
-
if (mrb_nil_p(tmp)) {
|
|
573
|
-
|
|
572
|
+
if (mrb_nil_p(tmp) || !mrb_fixnum_p(tmp)) {
|
|
573
|
+
tmp = mrb_to_integer(mrb, val, "to_i");
|
|
574
574
|
}
|
|
575
575
|
return tmp;
|
|
576
576
|
}
|
|
@@ -926,7 +926,7 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
|
|
|
926
926
|
else {
|
|
927
927
|
mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1);
|
|
928
928
|
|
|
929
|
-
if (
|
|
929
|
+
if (mrb_nil_p(tmp)) return mrb_nil_value();
|
|
930
930
|
if (!mrb_fixnum_p(tmp)) {
|
|
931
931
|
return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp);
|
|
932
932
|
}
|
|
@@ -2542,10 +2542,10 @@ mrb_str_dump(mrb_state *mrb, mrb_value str)
|
|
|
2542
2542
|
}
|
|
2543
2543
|
else {
|
|
2544
2544
|
*q++ = '\\';
|
|
2545
|
-
q
|
|
2546
|
-
q[1] =
|
|
2547
|
-
q[0] =
|
|
2548
|
-
q +=
|
|
2545
|
+
*q++ = 'x';
|
|
2546
|
+
q[1] = mrb_digitmap[c % 16]; c /= 16;
|
|
2547
|
+
q[0] = mrb_digitmap[c % 16];
|
|
2548
|
+
q += 2;
|
|
2549
2549
|
}
|
|
2550
2550
|
}
|
|
2551
2551
|
}
|
|
@@ -2685,9 +2685,9 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str)
|
|
|
2685
2685
|
}
|
|
2686
2686
|
else {
|
|
2687
2687
|
buf[0] = '\\';
|
|
2688
|
-
buf[
|
|
2689
|
-
buf[
|
|
2690
|
-
buf[
|
|
2688
|
+
buf[1] = 'x';
|
|
2689
|
+
buf[3] = mrb_digitmap[c % 16]; c /= 16;
|
|
2690
|
+
buf[2] = mrb_digitmap[c % 16];
|
|
2691
2691
|
mrb_str_cat(mrb, result, buf, 4);
|
|
2692
2692
|
continue;
|
|
2693
2693
|
}
|
|
@@ -955,27 +955,61 @@ find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c)
|
|
|
955
955
|
return arg.sym;
|
|
956
956
|
}
|
|
957
957
|
|
|
958
|
+
static struct RClass*
|
|
959
|
+
outer_class(mrb_state *mrb, struct RClass *c)
|
|
960
|
+
{
|
|
961
|
+
mrb_value ov;
|
|
962
|
+
|
|
963
|
+
ov = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
|
|
964
|
+
if (mrb_nil_p(ov)) return NULL;
|
|
965
|
+
switch (mrb_type(ov)) {
|
|
966
|
+
case MRB_TT_CLASS:
|
|
967
|
+
case MRB_TT_MODULE:
|
|
968
|
+
return mrb_class_ptr(ov);
|
|
969
|
+
default:
|
|
970
|
+
break;
|
|
971
|
+
}
|
|
972
|
+
return NULL;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
static mrb_bool
|
|
976
|
+
detect_outer_loop(mrb_state *mrb, struct RClass *c)
|
|
977
|
+
{
|
|
978
|
+
struct RClass *t = c; /* tortoise */
|
|
979
|
+
struct RClass *h = c; /* hare */
|
|
980
|
+
|
|
981
|
+
for (;;) {
|
|
982
|
+
if (h == NULL) return FALSE;
|
|
983
|
+
h = outer_class(mrb, h);
|
|
984
|
+
if (h == NULL) return FALSE;
|
|
985
|
+
h = outer_class(mrb, h);
|
|
986
|
+
t = outer_class(mrb, t);
|
|
987
|
+
if (t == h) return TRUE;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
958
991
|
mrb_value
|
|
959
992
|
mrb_class_find_path(mrb_state *mrb, struct RClass *c)
|
|
960
993
|
{
|
|
961
|
-
|
|
994
|
+
struct RClass *outer;
|
|
995
|
+
mrb_value path;
|
|
962
996
|
mrb_sym name;
|
|
963
997
|
const char *str;
|
|
964
998
|
mrb_int len;
|
|
965
|
-
mrb_sym osym = mrb_intern_lit(mrb, "__outer__");
|
|
966
999
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1000
|
+
if (detect_outer_loop(mrb, c)) return mrb_nil_value();
|
|
1001
|
+
outer = outer_class(mrb, c);
|
|
1002
|
+
if (outer == NULL) return mrb_nil_value();
|
|
1003
|
+
name = find_class_sym(mrb, outer, c);
|
|
970
1004
|
if (name == 0) return mrb_nil_value();
|
|
971
|
-
str = mrb_class_name(mrb,
|
|
1005
|
+
str = mrb_class_name(mrb, outer);
|
|
972
1006
|
path = mrb_str_new_capa(mrb, 40);
|
|
973
1007
|
mrb_str_cat_cstr(mrb, path, str);
|
|
974
1008
|
mrb_str_cat_cstr(mrb, path, "::");
|
|
975
1009
|
|
|
976
1010
|
str = mrb_sym2name_len(mrb, name, &len);
|
|
977
1011
|
mrb_str_cat(mrb, path, str, len);
|
|
978
|
-
iv_del(mrb, c->iv,
|
|
1012
|
+
iv_del(mrb, c->iv, mrb_intern_lit(mrb, "__outer__"), NULL);
|
|
979
1013
|
iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path);
|
|
980
1014
|
mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path);
|
|
981
1015
|
return path;
|
data/resources/mruby/src/vm.c
CHANGED
|
@@ -516,7 +516,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
|
|
|
516
516
|
}
|
|
517
517
|
ci->nregs = p->body.irep->nregs;
|
|
518
518
|
if (ci->argc < 0) keep = 3;
|
|
519
|
-
else keep = ci->argc +
|
|
519
|
+
else keep = ci->argc + 2;
|
|
520
520
|
if (ci->nregs < keep) {
|
|
521
521
|
stack_extend(mrb, keep);
|
|
522
522
|
}
|
|
@@ -1351,6 +1351,7 @@ RETRY_TRY_BLOCK:
|
|
|
1351
1351
|
for (n=0; n<a; n++) {
|
|
1352
1352
|
proc = mrb->c->ensure[epos+n];
|
|
1353
1353
|
mrb->c->ensure[epos+n] = NULL;
|
|
1354
|
+
if (proc == NULL) continue;
|
|
1354
1355
|
irep = proc->body.irep;
|
|
1355
1356
|
ci = cipush(mrb);
|
|
1356
1357
|
ci->mid = ci[-1].mid;
|
|
@@ -1661,6 +1662,9 @@ RETRY_TRY_BLOCK:
|
|
|
1661
1662
|
if (MRB_METHOD_CFUNC_P(m)) {
|
|
1662
1663
|
mrb_value v;
|
|
1663
1664
|
ci->nregs = (argc < 0) ? 3 : n+2;
|
|
1665
|
+
if (MRB_METHOD_PROC_P(m)) {
|
|
1666
|
+
ci->proc = MRB_METHOD_PROC(m);
|
|
1667
|
+
}
|
|
1664
1668
|
v = MRB_METHOD_CFUNC(m)(mrb, recv);
|
|
1665
1669
|
mrb_gc_arena_restore(mrb, ai);
|
|
1666
1670
|
if (mrb->exc) goto L_RAISE;
|
|
@@ -2934,9 +2938,6 @@ RETRY_TRY_BLOCK:
|
|
|
2934
2938
|
CASE(OP_STOP) {
|
|
2935
2939
|
/* stop VM */
|
|
2936
2940
|
L_STOP:
|
|
2937
|
-
while (mrb->c->ci > mrb->c->cibase) {
|
|
2938
|
-
cipop(mrb);
|
|
2939
|
-
}
|
|
2940
2941
|
while (mrb->c->eidx > 0) {
|
|
2941
2942
|
ecall(mrb);
|
|
2942
2943
|
}
|