diff options
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby/src')
34 files changed, 0 insertions, 22412 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/src/array.c b/web/server/h2o/libh2o/deps/mruby/src/array.c deleted file mode 100644 index 8f33defe6..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/array.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* -** array.c - Array class -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/string.h> -#include <mruby/range.h> -#include "value_array.h" - -#define ARY_DEFAULT_LEN 4 -#define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ -#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) -#define ARY_MAX_SIZE ((mrb_int)((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? ARY_C_MAX_SIZE : MRB_INT_MAX-1)) - -static struct RArray* -ary_new_capa(mrb_state *mrb, mrb_int capa) -{ - struct RArray *a; - size_t blen; - - if (capa > ARY_MAX_SIZE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - blen = capa * sizeof(mrb_value); - - a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); - if (capa <= MRB_ARY_EMBED_LEN_MAX) { - ARY_SET_EMBED_LEN(a, 0); - } - else { - a->as.heap.ptr = (mrb_value *)mrb_malloc(mrb, blen); - a->as.heap.aux.capa = capa; - a->as.heap.len = 0; - } - - return a; -} - -MRB_API mrb_value -mrb_ary_new_capa(mrb_state *mrb, mrb_int capa) -{ - struct RArray *a = ary_new_capa(mrb, capa); - return mrb_obj_value(a); -} - -MRB_API mrb_value -mrb_ary_new(mrb_state *mrb) -{ - return mrb_ary_new_capa(mrb, 0); -} - -/* - * to copy array, use this instead of memcpy because of portability - * * gcc on ARM may fail optimization of memcpy - * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html - * * gcc on MIPS also fail - * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755 - * * memcpy doesn't exist on freestanding environment - * - * If you optimize for binary size, use memcpy instead of this at your own risk - * of above portability issue. - * - * see also http://togetter.com/li/462898 - * - */ -static inline void -array_copy(mrb_value *dst, const mrb_value *src, mrb_int size) -{ - mrb_int i; - - for (i = 0; i < size; i++) { - dst[i] = src[i]; - } -} - -MRB_API mrb_value -mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals) -{ - struct RArray *a = ary_new_capa(mrb, size); - - array_copy(ARY_PTR(a), vals, size); - ARY_SET_LEN(a, size); - - return mrb_obj_value(a); -} - -MRB_API mrb_value -mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr) -{ - struct RArray *a; - - a = ary_new_capa(mrb, 2); - ARY_PTR(a)[0] = car; - ARY_PTR(a)[1] = cdr; - ARY_SET_LEN(a, 2); - return mrb_obj_value(a); -} - -static void -ary_fill_with_nil(mrb_value *ptr, mrb_int size) -{ - mrb_value nil = mrb_nil_value(); - - while (size--) { - *ptr++ = nil; - } -} - -static void -ary_modify_check(mrb_state *mrb, struct RArray *a) -{ - if (MRB_FROZEN_P(a)) { - mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array"); - } -} - -static void -ary_modify(mrb_state *mrb, struct RArray *a) -{ - ary_modify_check(mrb, a); - - if (ARY_SHARED_P(a)) { - mrb_shared_array *shared = a->as.heap.aux.shared; - - if (shared->refcnt == 1 && a->as.heap.ptr == shared->ptr) { - a->as.heap.ptr = shared->ptr; - a->as.heap.aux.capa = a->as.heap.len; - mrb_free(mrb, shared); - } - else { - mrb_value *ptr, *p; - mrb_int len; - - p = a->as.heap.ptr; - len = a->as.heap.len * sizeof(mrb_value); - ptr = (mrb_value *)mrb_malloc(mrb, len); - if (p) { - array_copy(ptr, p, a->as.heap.len); - } - a->as.heap.ptr = ptr; - a->as.heap.aux.capa = a->as.heap.len; - mrb_ary_decref(mrb, shared); - } - ARY_UNSET_SHARED_FLAG(a); - } -} - -MRB_API void -mrb_ary_modify(mrb_state *mrb, struct RArray* a) -{ - mrb_write_barrier(mrb, (struct RBasic*)a); - ary_modify(mrb, a); -} - -static void -ary_make_shared(mrb_state *mrb, struct RArray *a) -{ - if (!ARY_SHARED_P(a) && !ARY_EMBED_P(a)) { - mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array)); - mrb_value *ptr = a->as.heap.ptr; - mrb_int len = a->as.heap.len; - - shared->refcnt = 1; - if (a->as.heap.aux.capa > len) { - a->as.heap.ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1); - } - else { - shared->ptr = ptr; - } - shared->len = len; - a->as.heap.aux.shared = shared; - ARY_SET_SHARED_FLAG(a); - } -} - -static void -ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) -{ - mrb_int capa = ARY_CAPA(a); - - if (len > ARY_MAX_SIZE || len < 0) { - size_error: - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - - if (capa < ARY_DEFAULT_LEN) { - capa = ARY_DEFAULT_LEN; - } - while (capa < len) { - if (capa <= ARY_MAX_SIZE / 2) { - capa *= 2; - } - else { - capa = len; - } - } - if (capa < len || capa > ARY_MAX_SIZE) { - goto size_error; - } - - if (ARY_EMBED_P(a)) { - mrb_value *ptr = ARY_EMBED_PTR(a); - mrb_int len = ARY_EMBED_LEN(a); - mrb_value *expanded_ptr = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*capa); - - ARY_UNSET_EMBED_FLAG(a); - array_copy(expanded_ptr, ptr, len); - a->as.heap.len = len; - a->as.heap.aux.capa = capa; - a->as.heap.ptr = expanded_ptr; - } - else if (capa > a->as.heap.aux.capa) { - mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); - - a->as.heap.aux.capa = capa; - a->as.heap.ptr = expanded_ptr; - } -} - -static void -ary_shrink_capa(mrb_state *mrb, struct RArray *a) -{ - - mrb_int capa; - - if (ARY_EMBED_P(a)) return; - - capa = a->as.heap.aux.capa; - if (capa < ARY_DEFAULT_LEN * 2) return; - if (capa <= a->as.heap.len * ARY_SHRINK_RATIO) return; - - do { - capa /= 2; - if (capa < ARY_DEFAULT_LEN) { - capa = ARY_DEFAULT_LEN; - break; - } - } while (capa > a->as.heap.len * ARY_SHRINK_RATIO); - - if (capa > a->as.heap.len && capa < a->as.heap.aux.capa) { - a->as.heap.aux.capa = capa; - a->as.heap.ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); - } -} - -MRB_API mrb_value -mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len) -{ - mrb_int old_len; - struct RArray *a = mrb_ary_ptr(ary); - - ary_modify(mrb, a); - old_len = RARRAY_LEN(ary); - if (old_len != new_len) { - ARY_SET_LEN(a, new_len); - if (new_len < old_len) { - ary_shrink_capa(mrb, a); - } - else { - ary_expand_capa(mrb, a, new_len); - ary_fill_with_nil(ARY_PTR(a) + old_len, new_len - old_len); - } - } - - return ary; -} - -static mrb_value -mrb_ary_s_create(mrb_state *mrb, mrb_value klass) -{ - mrb_value ary; - mrb_value *vals; - mrb_int len; - struct RArray *a; - - mrb_get_args(mrb, "*!", &vals, &len); - ary = mrb_ary_new_from_values(mrb, len, vals); - a = mrb_ary_ptr(ary); - a->c = mrb_class_ptr(klass); - - return ary; -} - -static void -ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2) -{ - mrb_int len; - - if (ARY_LEN(a2) > ARY_MAX_SIZE - ARY_LEN(a)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - len = ARY_LEN(a) + ARY_LEN(a2); - - ary_modify(mrb, a); - if (ARY_CAPA(a) < len) { - ary_expand_capa(mrb, a, len); - } - array_copy(ARY_PTR(a)+ARY_LEN(a), ARY_PTR(a2), ARY_LEN(a2)); - mrb_write_barrier(mrb, (struct RBasic*)a); - ARY_SET_LEN(a, len); -} - -MRB_API void -mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other) -{ - struct RArray *a2 = mrb_ary_ptr(other); - - ary_concat(mrb, mrb_ary_ptr(self), a2); -} - -static mrb_value -mrb_ary_concat_m(mrb_state *mrb, mrb_value self) -{ - mrb_value ary; - - mrb_get_args(mrb, "A", &ary); - mrb_ary_concat(mrb, self, ary); - return self; -} - -static mrb_value -mrb_ary_plus(mrb_state *mrb, mrb_value self) -{ - struct RArray *a1 = mrb_ary_ptr(self); - struct RArray *a2; - mrb_value *ptr; - mrb_int blen, len1; - - mrb_get_args(mrb, "a", &ptr, &blen); - if (ARY_MAX_SIZE - blen < ARY_LEN(a1)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - len1 = ARY_LEN(a1); - a2 = ary_new_capa(mrb, len1 + blen); - array_copy(ARY_PTR(a2), ARY_PTR(a1), len1); - array_copy(ARY_PTR(a2) + len1, ptr, blen); - ARY_SET_LEN(a2, len1+blen); - - return mrb_obj_value(a2); -} - -static void -ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len) -{ - ary_modify(mrb, a); - if (ARY_CAPA(a) < len) - ary_expand_capa(mrb, a, len); - array_copy(ARY_PTR(a), argv, len); - mrb_write_barrier(mrb, (struct RBasic*)a); - ARY_SET_LEN(a, len); -} - -MRB_API void -mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other) -{ - struct RArray *a1 = mrb_ary_ptr(self); - struct RArray *a2 = mrb_ary_ptr(other); - - if (a1 != a2) { - ary_replace(mrb, a1, ARY_PTR(a2), ARY_LEN(a2)); - } -} - -static mrb_value -mrb_ary_replace_m(mrb_state *mrb, mrb_value self) -{ - mrb_value other; - - mrb_get_args(mrb, "A", &other); - mrb_ary_replace(mrb, self, other); - - return self; -} - -static mrb_value -mrb_ary_times(mrb_state *mrb, mrb_value self) -{ - struct RArray *a1 = mrb_ary_ptr(self); - struct RArray *a2; - mrb_value *ptr; - mrb_int times, len1; - - mrb_get_args(mrb, "i", ×); - if (times < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); - } - if (times == 0) return mrb_ary_new(mrb); - if (ARY_MAX_SIZE / times < ARY_LEN(a1)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - len1 = ARY_LEN(a1); - a2 = ary_new_capa(mrb, len1 * times); - ARY_SET_LEN(a2, len1 * times); - ptr = ARY_PTR(a2); - while (times--) { - array_copy(ptr, ARY_PTR(a1), len1); - ptr += len1; - } - - return mrb_obj_value(a2); -} - -static mrb_value -mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_int len = ARY_LEN(a); - - if (len > 1) { - mrb_value *p1, *p2; - - ary_modify(mrb, a); - p1 = ARY_PTR(a); - p2 = p1 + len - 1; - - while (p1 < p2) { - mrb_value tmp = *p1; - *p1++ = *p2; - *p2-- = tmp; - } - } - return self; -} - -static mrb_value -mrb_ary_reverse(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, ARY_LEN(a)); - mrb_int len = ARY_LEN(a); - - if (len > 0) { - mrb_value *p1, *p2, *e; - - p1 = ARY_PTR(a); - e = p1 + len; - p2 = ARY_PTR(b) + len - 1; - while (p1 < e) { - *p2-- = *p1++; - } - ARY_SET_LEN(b, len); - } - return mrb_obj_value(b); -} - -MRB_API void -mrb_ary_push(mrb_state *mrb, mrb_value ary, mrb_value elem) -{ - struct RArray *a = mrb_ary_ptr(ary); - mrb_int len = ARY_LEN(a); - - ary_modify(mrb, a); - if (len == ARY_CAPA(a)) - ary_expand_capa(mrb, a, len + 1); - ARY_PTR(a)[len] = elem; - ARY_SET_LEN(a, len+1); - mrb_field_write_barrier_value(mrb, (struct RBasic*)a, elem); -} - -static mrb_value -mrb_ary_push_m(mrb_state *mrb, mrb_value self) -{ - mrb_value *argv; - mrb_int len, len2, alen; - struct RArray *a; - - mrb_get_args(mrb, "*!", &argv, &alen); - a = mrb_ary_ptr(self); - ary_modify(mrb, a); - len = ARY_LEN(a); - len2 = len + alen; - if (ARY_CAPA(a) < len2) { - ary_expand_capa(mrb, a, len2); - } - array_copy(ARY_PTR(a)+len, argv, alen); - ARY_SET_LEN(a, len2); - mrb_write_barrier(mrb, (struct RBasic*)a); - - return self; -} - -MRB_API mrb_value -mrb_ary_pop(mrb_state *mrb, mrb_value ary) -{ - struct RArray *a = mrb_ary_ptr(ary); - mrb_int len = ARY_LEN(a); - - ary_modify_check(mrb, a); - if (len == 0) return mrb_nil_value(); - ARY_SET_LEN(a, len-1); - return ARY_PTR(a)[len-1]; -} - -#define ARY_SHIFT_SHARED_MIN 10 - -MRB_API mrb_value -mrb_ary_shift(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_int len = ARY_LEN(a); - mrb_value val; - - ary_modify_check(mrb, a); - if (len == 0) return mrb_nil_value(); - if (ARY_SHARED_P(a)) { - L_SHIFT: - val = a->as.heap.ptr[0]; - a->as.heap.ptr++; - a->as.heap.len--; - return val; - } - if (len > ARY_SHIFT_SHARED_MIN) { - ary_make_shared(mrb, a); - goto L_SHIFT; - } - else { - mrb_value *ptr = ARY_PTR(a); - mrb_int size = len; - - val = *ptr; - while (--size) { - *ptr = *(ptr+1); - ++ptr; - } - ARY_SET_LEN(a, len-1); - } - return val; -} - -/* self = [1,2,3] - item = 0 - self.unshift item - p self #=> [0, 1, 2, 3] */ -MRB_API mrb_value -mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_int len = ARY_LEN(a); - - if (ARY_SHARED_P(a) - && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */ - && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= 1) /* there's room for unshifted item */ { - a->as.heap.ptr--; - a->as.heap.ptr[0] = item; - } - else { - mrb_value *ptr; - - ary_modify(mrb, a); - if (ARY_CAPA(a) < len + 1) - ary_expand_capa(mrb, a, len + 1); - ptr = ARY_PTR(a); - value_move(ptr + 1, ptr, len); - ptr[0] = item; - } - ARY_SET_LEN(a, len+1); - mrb_field_write_barrier_value(mrb, (struct RBasic*)a, item); - - return self; -} - -static mrb_value -mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_value *vals, *ptr; - mrb_int alen, len; - - mrb_get_args(mrb, "*!", &vals, &alen); - if (alen == 0) { - ary_modify_check(mrb, a); - return self; - } - len = ARY_LEN(a); - if (alen > ARY_MAX_SIZE - len) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - if (ARY_SHARED_P(a) - && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */ - && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= alen) /* there's room for unshifted item */ { - ary_modify_check(mrb, a); - a->as.heap.ptr -= alen; - ptr = a->as.heap.ptr; - } - else { - ary_modify(mrb, a); - if (ARY_CAPA(a) < len + alen) - ary_expand_capa(mrb, a, len + alen); - ptr = ARY_PTR(a); - value_move(ptr + alen, ptr, len); - } - array_copy(ptr, vals, alen); - ARY_SET_LEN(a, len+alen); - while (alen--) { - mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[alen]); - } - - return self; -} - -MRB_API mrb_value -mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) -{ - struct RArray *a = mrb_ary_ptr(ary); - mrb_int len = ARY_LEN(a); - - /* range check */ - if (n < 0) n += len; - if (n < 0 || len <= n) return mrb_nil_value(); - - return ARY_PTR(a)[n]; -} - -MRB_API void -mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) -{ - struct RArray *a = mrb_ary_ptr(ary); - mrb_int len = ARY_LEN(a); - - ary_modify(mrb, a); - /* range check */ - if (n < 0) { - n += len; - if (n < 0) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of array", mrb_fixnum_value(n - len)); - } - } - if (len <= n) { - if (ARY_CAPA(a) <= n) - ary_expand_capa(mrb, a, n + 1); - ary_fill_with_nil(ARY_PTR(a) + len, n + 1 - len); - ARY_SET_LEN(a, n+1); - } - - ARY_PTR(a)[n] = val; - mrb_field_write_barrier_value(mrb, (struct RBasic*)a, val); -} - -static struct RArray* -ary_dup(mrb_state *mrb, struct RArray *a) -{ - mrb_int len = ARY_LEN(a); - struct RArray *d = ary_new_capa(mrb, len); - - ary_replace(mrb, d, ARY_PTR(a), len); - return d; -} - -MRB_API mrb_value -mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl) -{ - struct RArray *a = mrb_ary_ptr(ary); - mrb_int alen = ARY_LEN(a); - const mrb_value *argv; - mrb_int argc; - mrb_int tail; - - ary_modify(mrb, a); - - /* len check */ - if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%S)", mrb_fixnum_value(len)); - - /* range check */ - if (head < 0) { - head += alen; - if (head < 0) { - mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); - } - } - tail = head + len; - if (alen < len || alen < tail) { - len = alen - head; - } - - /* size check */ - if (mrb_array_p(rpl)) { - argc = RARRAY_LEN(rpl); - argv = RARRAY_PTR(rpl); - if (argv == ARY_PTR(a)) { - struct RArray *r; - - if (argc > 32767) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "too big recursive splice"); - } - r = ary_dup(mrb, a); - argv = ARY_PTR(r); - } - } - else { - argc = 1; - argv = &rpl; - } - if (head >= alen) { - if (head > ARY_MAX_SIZE - argc) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head)); - } - len = head + argc; - if (len > ARY_CAPA(a)) { - ary_expand_capa(mrb, a, head + argc); - } - ary_fill_with_nil(ARY_PTR(a) + alen, head - alen); - if (argc > 0) { - array_copy(ARY_PTR(a) + head, argv, argc); - } - ARY_SET_LEN(a, len); - } - else { - mrb_int newlen; - - if (alen - len > ARY_MAX_SIZE - argc) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(alen + argc - len)); - } - newlen = alen + argc - len; - if (newlen > ARY_CAPA(a)) { - ary_expand_capa(mrb, a, newlen); - } - - if (len != argc) { - mrb_value *ptr = ARY_PTR(a); - tail = head + len; - value_move(ptr + head + argc, ptr + tail, alen - tail); - ARY_SET_LEN(a, newlen); - } - if (argc > 0) { - value_move(ARY_PTR(a) + head, argv, argc); - } - } - mrb_write_barrier(mrb, (struct RBasic*)a); - return ary; -} - -void -mrb_ary_decref(mrb_state *mrb, mrb_shared_array *shared) -{ - shared->refcnt--; - if (shared->refcnt == 0) { - mrb_free(mrb, shared->ptr); - mrb_free(mrb, shared); - } -} - -static mrb_value -ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len) -{ - struct RArray *b; - - if (!ARY_SHARED_P(a) && len <= ARY_SHIFT_SHARED_MIN) { - return mrb_ary_new_from_values(mrb, len, ARY_PTR(a)+beg); - } - ary_make_shared(mrb, a); - b = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); - b->as.heap.ptr = a->as.heap.ptr + beg; - b->as.heap.len = len; - b->as.heap.aux.shared = a->as.heap.aux.shared; - b->as.heap.aux.shared->refcnt++; - ARY_SET_SHARED_FLAG(b); - - return mrb_obj_value(b); -} - -static mrb_int -aget_index(mrb_state *mrb, mrb_value index) -{ - if (mrb_fixnum_p(index)) { - return mrb_fixnum(index); - } - else if (mrb_float_p(index)) { - return (mrb_int)mrb_float(index); - } - else { - mrb_int i, argc; - mrb_value *argv; - - mrb_get_args(mrb, "i*!", &i, &argv, &argc); - return i; - } -} - -/* - * call-seq: - * ary[index] -> obj or nil - * ary[start, length] -> new_ary or nil - * ary[range] -> new_ary or nil - * ary.slice(index) -> obj or nil - * ary.slice(start, length) -> new_ary or nil - * ary.slice(range) -> new_ary or nil - * - * Element Reference --- Returns the element at +index+, or returns a - * subarray starting at the +start+ index and continuing for +length+ - * elements, or returns a subarray specified by +range+ of indices. - * - * Negative indices count backward from the end of the array (-1 is the last - * element). For +start+ and +range+ cases the starting index is just before - * an element. Additionally, an empty array is returned when the starting - * index for an element range is at the end of the array. - * - * Returns +nil+ if the index (or starting index) are out of range. - * - * a = [ "a", "b", "c", "d", "e" ] - * a[1] => "b" - * a[1,2] => ["b", "c"] - * a[1..-2] => ["b", "c", "d"] - * - */ - -static mrb_value -mrb_ary_aget(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_int i, len, alen = ARY_LEN(a); - mrb_value index; - - if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { - switch (mrb_type(index)) { - /* a[n..m] */ - case MRB_TT_RANGE: - if (mrb_range_beg_len(mrb, index, &i, &len, alen, TRUE) == 1) { - return ary_subseq(mrb, a, i, len); - } - else { - return mrb_nil_value(); - } - case MRB_TT_FIXNUM: - return mrb_ary_ref(mrb, self, mrb_fixnum(index)); - default: - return mrb_ary_ref(mrb, self, aget_index(mrb, index)); - } - } - - i = aget_index(mrb, index); - if (i < 0) i += alen; - if (i < 0 || alen < i) return mrb_nil_value(); - if (len < 0) return mrb_nil_value(); - if (alen == i) return mrb_ary_new(mrb); - if (len > alen - i) len = alen - i; - - return ary_subseq(mrb, a, i, len); -} - -/* - * call-seq: - * ary[index] = obj -> obj - * ary[start, length] = obj or other_ary or nil -> obj or other_ary or nil - * ary[range] = obj or other_ary or nil -> obj or other_ary or nil - * - * Element Assignment --- Sets the element at +index+, or replaces a subarray - * from the +start+ index for +length+ elements, or replaces a subarray - * specified by the +range+ of indices. - * - * If indices are greater than the current capacity of the array, the array - * grows automatically. Elements are inserted into the array at +start+ if - * +length+ is zero. - * - * Negative indices will count backward from the end of the array. For - * +start+ and +range+ cases the starting index is just before an element. - * - * An IndexError is raised if a negative index points past the beginning of - * the array. - * - * See also Array#push, and Array#unshift. - * - * a = Array.new - * a[4] = "4"; #=> [nil, nil, nil, nil, "4"] - * a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"] - * a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"] - * a[0, 2] = "?" #=> ["?", 2, nil, "4"] - * a[0..2] = "A" #=> ["A", "4"] - * a[-1] = "Z" #=> ["A", "Z"] - * a[1..-1] = nil #=> ["A", nil] - * a[1..-1] = [] #=> ["A"] - * a[0, 0] = [ 1, 2 ] #=> [1, 2, "A"] - * a[3, 0] = "B" #=> [1, 2, "A", "B"] - */ - -static mrb_value -mrb_ary_aset(mrb_state *mrb, mrb_value self) -{ - mrb_value v1, v2, v3; - mrb_int i, len; - - mrb_ary_modify(mrb, mrb_ary_ptr(self)); - if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) { - /* a[n..m] = v */ - switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) { - case 0: /* not range */ - mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); - break; - case 1: /* range */ - mrb_ary_splice(mrb, self, i, len, v2); - break; - case 2: /* out of range */ - mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1); - break; - } - return v2; - } - - /* a[n,m] = v */ - mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3); - return v3; -} - -static mrb_value -mrb_ary_delete_at(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_int index; - mrb_value val; - mrb_value *ptr; - mrb_int len, alen = ARY_LEN(a); - - mrb_get_args(mrb, "i", &index); - if (index < 0) index += alen; - if (index < 0 || alen <= index) return mrb_nil_value(); - - ary_modify(mrb, a); - ptr = ARY_PTR(a); - val = ptr[index]; - - ptr += index; - len = alen - index; - while (--len) { - *ptr = *(ptr+1); - ++ptr; - } - ARY_SET_LEN(a, alen-1); - - ary_shrink_capa(mrb, a); - - return val; -} - -static mrb_value -mrb_ary_first(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_int size, alen = ARY_LEN(a); - - if (mrb->c->ci->argc == 0) { - return (alen > 0)? ARY_PTR(a)[0]: mrb_nil_value(); - } - mrb_get_args(mrb, "|i", &size); - if (size < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); - } - - if (size > alen) size = alen; - if (ARY_SHARED_P(a)) { - return ary_subseq(mrb, a, 0, size); - } - return mrb_ary_new_from_values(mrb, size, ARY_PTR(a)); -} - -static mrb_value -mrb_ary_last(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - mrb_int size, alen = ARY_LEN(a); - - if (mrb_get_args(mrb, "|i", &size) == 0) - return (alen > 0)? ARY_PTR(a)[alen - 1]: mrb_nil_value(); - - if (size < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); - } - if (size > alen) size = alen; - if (ARY_SHARED_P(a) || size > ARY_DEFAULT_LEN) { - return ary_subseq(mrb, a, alen - size, size); - } - return mrb_ary_new_from_values(mrb, size, ARY_PTR(a) + alen - size); -} - -static mrb_value -mrb_ary_index_m(mrb_state *mrb, mrb_value self) -{ - mrb_value obj; - mrb_int i; - - mrb_get_args(mrb, "o", &obj); - for (i = 0; i < RARRAY_LEN(self); i++) { - if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { - return mrb_fixnum_value(i); - } - } - return mrb_nil_value(); -} - -static mrb_value -mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) -{ - mrb_value obj; - mrb_int i, len; - - mrb_get_args(mrb, "o", &obj); - for (i = RARRAY_LEN(self) - 1; i >= 0; i--) { - if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { - return mrb_fixnum_value(i); - } - if (i > (len = RARRAY_LEN(self))) { - i = len; - } - } - return mrb_nil_value(); -} - -MRB_API mrb_value -mrb_ary_splat(mrb_state *mrb, mrb_value v) -{ - mrb_value a, recv_class; - - if (mrb_array_p(v)) { - return v; - } - - if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) { - return mrb_ary_new_from_values(mrb, 1, &v); - } - - a = mrb_funcall(mrb, v, "to_a", 0); - if (mrb_array_p(a)) { - return a; - } - else if (mrb_nil_p(a)) { - return mrb_ary_new_from_values(mrb, 1, &v); - } - else { - recv_class = mrb_obj_value(mrb_obj_class(mrb, v)); - mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)", - recv_class, - recv_class, - mrb_obj_value(mrb_obj_class(mrb, a)) - ); - /* not reached */ - return mrb_undef_value(); - } -} - -static mrb_value -mrb_ary_size(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - - return mrb_fixnum_value(ARY_LEN(a)); -} - -MRB_API mrb_value -mrb_ary_clear(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - - ary_modify(mrb, a); - if (ARY_SHARED_P(a)) { - mrb_ary_decref(mrb, a->as.heap.aux.shared); - ARY_UNSET_SHARED_FLAG(a); - } - else if (!ARY_EMBED_P(a)){ - mrb_free(mrb, a->as.heap.ptr); - } - ARY_SET_EMBED_LEN(a, 0); - - return self; -} - -static mrb_value -mrb_ary_empty_p(mrb_state *mrb, mrb_value self) -{ - struct RArray *a = mrb_ary_ptr(self); - - return mrb_bool_value(ARY_LEN(a) == 0); -} - -MRB_API mrb_value -mrb_check_array_type(mrb_state *mrb, mrb_value ary) -{ - return mrb_check_convert_type(mrb, ary, MRB_TT_ARRAY, "Array", "to_ary"); -} - -MRB_API mrb_value -mrb_ary_entry(mrb_value ary, mrb_int offset) -{ - if (offset < 0) { - offset += RARRAY_LEN(ary); - } - if (offset < 0 || RARRAY_LEN(ary) <= offset) { - return mrb_nil_value(); - } - return RARRAY_PTR(ary)[offset]; -} - -static mrb_value -join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list) -{ - mrb_int i; - mrb_value result, val, tmp; - - /* check recursive */ - for (i=0; i<RARRAY_LEN(list); i++) { - if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "recursive array join"); - } - } - - mrb_ary_push(mrb, list, ary); - - result = mrb_str_new_capa(mrb, 64); - - for (i=0; i<RARRAY_LEN(ary); i++) { - if (i > 0 && !mrb_nil_p(sep)) { - mrb_str_cat_str(mrb, result, sep); - } - - val = RARRAY_PTR(ary)[i]; - switch (mrb_type(val)) { - case MRB_TT_ARRAY: - ary_join: - val = join_ary(mrb, val, sep, list); - /* fall through */ - - case MRB_TT_STRING: - str_join: - mrb_str_cat_str(mrb, result, val); - break; - - default: - if (!mrb_immediate_p(val)) { - tmp = mrb_check_string_type(mrb, val); - if (!mrb_nil_p(tmp)) { - val = tmp; - goto str_join; - } - tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); - if (!mrb_nil_p(tmp)) { - val = tmp; - goto ary_join; - } - } - val = mrb_obj_as_string(mrb, val); - goto str_join; - } - } - - mrb_ary_pop(mrb, list); - - return result; -} - -MRB_API mrb_value -mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep) -{ - if (!mrb_nil_p(sep)) { - sep = mrb_obj_as_string(mrb, sep); - } - return join_ary(mrb, ary, sep, mrb_ary_new(mrb)); -} - -/* - * call-seq: - * ary.join(sep="") -> str - * - * Returns a string created by converting each element of the array to - * a string, separated by <i>sep</i>. - * - * [ "a", "b", "c" ].join #=> "abc" - * [ "a", "b", "c" ].join("-") #=> "a-b-c" - */ - -static mrb_value -mrb_ary_join_m(mrb_state *mrb, mrb_value ary) -{ - mrb_value sep = mrb_nil_value(); - - mrb_get_args(mrb, "|S!", &sep); - return mrb_ary_join(mrb, ary, sep); -} - -static mrb_value -mrb_ary_eq(mrb_state *mrb, mrb_value ary1) -{ - mrb_value ary2; - - mrb_get_args(mrb, "o", &ary2); - if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); - if (!mrb_array_p(ary2)) { - return mrb_false_value(); - } - if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); - - return ary2; -} - -static mrb_value -mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) -{ - mrb_value ary2; - - mrb_get_args(mrb, "o", &ary2); - if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0); - if (!mrb_array_p(ary2)) { - return mrb_nil_value(); - } - - return ary2; -} - -void -mrb_init_array(mrb_state *mrb) -{ - struct RClass *a; - - mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class); /* 15.2.12 */ - MRB_SET_INSTANCE_TT(a, MRB_TT_ARRAY); - - mrb_define_class_method(mrb, a, "[]", mrb_ary_s_create, MRB_ARGS_ANY()); /* 15.2.12.4.1 */ - - mrb_define_method(mrb, a, "+", mrb_ary_plus, MRB_ARGS_REQ(1)); /* 15.2.12.5.1 */ - mrb_define_method(mrb, a, "*", mrb_ary_times, MRB_ARGS_REQ(1)); /* 15.2.12.5.2 */ - mrb_define_method(mrb, a, "<<", mrb_ary_push_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.3 */ - mrb_define_method(mrb, a, "[]", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.4 */ - mrb_define_method(mrb, a, "[]=", mrb_ary_aset, MRB_ARGS_ANY()); /* 15.2.12.5.5 */ - mrb_define_method(mrb, a, "clear", mrb_ary_clear, MRB_ARGS_NONE()); /* 15.2.12.5.6 */ - mrb_define_method(mrb, a, "concat", mrb_ary_concat_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.8 */ - mrb_define_method(mrb, a, "delete_at", mrb_ary_delete_at, MRB_ARGS_REQ(1)); /* 15.2.12.5.9 */ - mrb_define_method(mrb, a, "empty?", mrb_ary_empty_p, MRB_ARGS_NONE()); /* 15.2.12.5.12 */ - mrb_define_method(mrb, a, "first", mrb_ary_first, MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */ - mrb_define_method(mrb, a, "index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */ - mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */ - mrb_define_method(mrb, a, "join", mrb_ary_join_m, MRB_ARGS_ANY()); /* 15.2.12.5.17 */ - mrb_define_method(mrb, a, "last", mrb_ary_last, MRB_ARGS_ANY()); /* 15.2.12.5.18 */ - mrb_define_method(mrb, a, "length", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.19 */ - mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */ - mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */ - mrb_define_method(mrb, a, "append", mrb_ary_push_m, MRB_ARGS_ANY()); - mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */ - mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */ - mrb_define_method(mrb, a, "reverse!", mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */ - mrb_define_method(mrb, a, "rindex", mrb_ary_rindex_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */ - mrb_define_method(mrb, a, "shift", mrb_ary_shift, MRB_ARGS_NONE()); /* 15.2.12.5.27 */ - mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */ - mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */ - mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ - mrb_define_method(mrb, a, "prepend", mrb_ary_unshift_m, MRB_ARGS_ANY()); - - mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, a, "__ary_index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */ -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/backtrace.c b/web/server/h2o/libh2o/deps/mruby/src/backtrace.c deleted file mode 100644 index 3e4e1a438..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/backtrace.c +++ /dev/null @@ -1,281 +0,0 @@ -/* -** backtrace.c - -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/variable.h> -#include <mruby/proc.h> -#include <mruby/array.h> -#include <mruby/string.h> -#include <mruby/class.h> -#include <mruby/debug.h> -#include <mruby/error.h> -#include <mruby/numeric.h> -#include <mruby/data.h> - -struct backtrace_location { - int lineno; - const char *filename; - mrb_sym method_id; -}; - -typedef void (*each_backtrace_func)(mrb_state*, struct backtrace_location*, void*); - -static const mrb_data_type bt_type = { "Backtrace", mrb_free }; - -static void -each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, mrb_code *pc0, each_backtrace_func func, void *data) -{ - ptrdiff_t i, j; - - if (ciidx >= mrb->c->ciend - mrb->c->cibase) - ciidx = 10; /* ciidx is broken... */ - - for (i=ciidx, j=0; i >= 0; i--,j++) { - struct backtrace_location loc; - mrb_callinfo *ci; - mrb_irep *irep; - mrb_code *pc; - - ci = &mrb->c->cibase[i]; - - if (!ci->proc) continue; - if (MRB_PROC_CFUNC_P(ci->proc)) continue; - - irep = ci->proc->body.irep; - if (!irep) continue; - - if (mrb->c->cibase[i].err) { - pc = mrb->c->cibase[i].err; - } - else if (i+1 <= ciidx) { - pc = mrb->c->cibase[i+1].pc - 1; - } - else { - pc = pc0; - } - loc.filename = mrb_debug_get_filename(irep, pc - irep->iseq); - loc.lineno = mrb_debug_get_line(irep, pc - irep->iseq); - - if (loc.lineno == -1) continue; - - if (!loc.filename) { - loc.filename = "(unknown)"; - } - - loc.method_id = ci->mid; - func(mrb, &loc, data); - } -} - -#ifndef MRB_DISABLE_STDIO - -static void -print_backtrace(mrb_state *mrb, mrb_value backtrace) -{ - int i, n; - FILE *stream = stderr; - - if (!mrb_array_p(backtrace)) return; - - n = RARRAY_LEN(backtrace) - 1; - if (n == 0) return; - - fprintf(stream, "trace:\n"); - for (i=0; i<n; i++) { - mrb_value entry = RARRAY_PTR(backtrace)[n-i-1]; - - if (mrb_string_p(entry)) { - fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry)); - } - } -} - -static int -packed_bt_len(struct backtrace_location *bt, int n) -{ - int len = 0; - int i; - - for (i=0; i<n; i++) { - if (!bt[i].filename && !bt[i].lineno && !bt[i].method_id) - continue; - len++; - } - return len; -} - -static void -print_packed_backtrace(mrb_state *mrb, mrb_value packed) -{ - FILE *stream = stderr; - struct backtrace_location *bt; - int n, i; - int ai = mrb_gc_arena_save(mrb); - - bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type); - if (bt == NULL) return; - n = (mrb_int)RDATA(packed)->flags; - - if (packed_bt_len(bt, n) == 0) return; - fprintf(stream, "trace:\n"); - for (i = 0; i<n; i++) { - struct backtrace_location *entry = &bt[n-i-1]; - if (entry->filename == NULL) continue; - fprintf(stream, "\t[%d] %s:%d", i, entry->filename, entry->lineno); - if (entry->method_id != 0) { - const char *method_name; - - method_name = mrb_sym2name(mrb, entry->method_id); - fprintf(stream, ":in %s", method_name); - mrb_gc_arena_restore(mrb, ai); - } - fprintf(stream, "\n"); - } -} - -/* mrb_print_backtrace - - function to retrieve backtrace information from the last exception. -*/ - -MRB_API void -mrb_print_backtrace(mrb_state *mrb) -{ - mrb_value backtrace; - - if (!mrb->exc) { - return; - } - - backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace")); - if (mrb_nil_p(backtrace)) return; - if (mrb_array_p(backtrace)) { - print_backtrace(mrb, backtrace); - } - else { - print_packed_backtrace(mrb, backtrace); - } -} -#else - -MRB_API void -mrb_print_backtrace(mrb_state *mrb) -{ -} - -#endif - -static void -count_backtrace_i(mrb_state *mrb, - struct backtrace_location *loc, - void *data) -{ - int *lenp = (int*)data; - - if (loc->filename == NULL) return; - (*lenp)++; -} - -static void -pack_backtrace_i(mrb_state *mrb, - struct backtrace_location *loc, - void *data) -{ - struct backtrace_location **pptr = (struct backtrace_location**)data; - struct backtrace_location *ptr = *pptr; - - if (loc->filename == NULL) return; - *ptr = *loc; - *pptr = ptr+1; -} - -static mrb_value -packed_backtrace(mrb_state *mrb) -{ - struct RData *backtrace; - ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase; - int len = 0; - int size; - void *ptr; - - each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len); - size = len * sizeof(struct backtrace_location); - ptr = mrb_malloc(mrb, size); - if (ptr) memset(ptr, 0, size); - backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); - backtrace->flags = (unsigned int)len; - each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr); - return mrb_obj_value(backtrace); -} - -void -mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) -{ - mrb_value backtrace; - int ai = mrb_gc_arena_save(mrb); - - backtrace = packed_backtrace(mrb); - mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace); - mrb_gc_arena_restore(mrb, ai); -} - -mrb_value -mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) -{ - struct backtrace_location *bt; - mrb_int n, i; - int ai; - - if (mrb_nil_p(backtrace)) { - empty_backtrace: - return mrb_ary_new_capa(mrb, 0); - } - if (mrb_array_p(backtrace)) return backtrace; - bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type); - if (bt == NULL) goto empty_backtrace; - n = (mrb_int)RDATA(backtrace)->flags; - backtrace = mrb_ary_new_capa(mrb, n); - ai = mrb_gc_arena_save(mrb); - for (i = 0; i < n; i++) { - struct backtrace_location *entry = &bt[i]; - mrb_value btline; - - if (entry->filename == NULL) continue; - btline = mrb_format(mrb, "%S:%S", - mrb_str_new_cstr(mrb, entry->filename), - mrb_fixnum_value(entry->lineno)); - if (entry->method_id != 0) { - mrb_str_cat_lit(mrb, btline, ":in "); - mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id)); - } - mrb_ary_push(mrb, backtrace, btline); - mrb_gc_arena_restore(mrb, ai); - } - - return backtrace; -} - -MRB_API mrb_value -mrb_exc_backtrace(mrb_state *mrb, mrb_value exc) -{ - mrb_sym attr_name; - mrb_value backtrace; - - attr_name = mrb_intern_lit(mrb, "backtrace"); - backtrace = mrb_iv_get(mrb, exc, attr_name); - if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) { - return backtrace; - } - backtrace = mrb_unpack_backtrace(mrb, backtrace); - mrb_iv_set(mrb, exc, attr_name, backtrace); - return backtrace; -} - -MRB_API mrb_value -mrb_get_backtrace(mrb_state *mrb) -{ - return mrb_unpack_backtrace(mrb, packed_backtrace(mrb)); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/class.c b/web/server/h2o/libh2o/deps/mruby/src/class.c deleted file mode 100644 index e3888001b..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/class.c +++ /dev/null @@ -1,2474 +0,0 @@ -/* -** class.c - Class class -** -** See Copyright Notice in mruby.h -*/ - -#include <stdarg.h> -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/numeric.h> -#include <mruby/proc.h> -#include <mruby/string.h> -#include <mruby/variable.h> -#include <mruby/error.h> -#include <mruby/data.h> -#include <mruby/istruct.h> - -KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal) - -void -mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) -{ - khiter_t k; - khash_t(mt) *h = c->mt; - - if (!h) return; - for (k = kh_begin(h); k != kh_end(h); k++) { - if (kh_exist(h, k)) { - struct RProc *m = kh_value(h, k); - if (m) { - mrb_gc_mark(mrb, (struct RBasic*)m); - } - } - } -} - -size_t -mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c) -{ - khash_t(mt) *h = c->mt; - - if (!h) return 0; - return kh_size(h); -} - -void -mrb_gc_free_mt(mrb_state *mrb, struct RClass *c) -{ - kh_destroy(mt, mrb, c->mt); -} - -void -mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) -{ - mrb_value name; - mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); - - if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return; - if (outer == NULL || outer == mrb->object_class) { - name = mrb_symbol_value(id); - } - else { - name = mrb_class_path(mrb, outer); - if (mrb_nil_p(name)) { /* unnamed outer class */ - if (outer != mrb->object_class) { - mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"), - mrb_obj_value(outer)); - } - return; - } - mrb_str_cat_cstr(mrb, name, "::"); - mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id)); - } - mrb_obj_iv_set(mrb, (struct RObject*)c, nsym, name); -} - -static void -setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) -{ - mrb_class_name_class(mrb, outer, c, id); - mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c)); -} - -#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c)) - -static void -prepare_singleton_class(mrb_state *mrb, struct RBasic *o) -{ - struct RClass *sc, *c; - - if (o->c->tt == MRB_TT_SCLASS) return; - sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); - sc->flags |= MRB_FLAG_IS_INHERITED; - sc->mt = kh_init(mt, mrb); - sc->iv = 0; - if (o->tt == MRB_TT_CLASS) { - c = (struct RClass*)o; - if (!c->super) { - sc->super = mrb->class_class; - } - else { - sc->super = c->super->c; - } - } - else if (o->tt == MRB_TT_SCLASS) { - c = (struct RClass*)o; - while (c->super->tt == MRB_TT_ICLASS) - c = c->super; - make_metaclass(mrb, c->super); - sc->super = c->super->c; - } - else { - sc->super = o->c; - prepare_singleton_class(mrb, (struct RBasic*)sc); - } - o->c = sc; - mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc); - mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o); - mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o)); -} - -static struct RClass* -class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) -{ - mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id); - - mrb_check_type(mrb, c, MRB_TT_CLASS); - return mrb_class_ptr(c); -} - -static struct RClass* -module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) -{ - mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id); - - mrb_check_type(mrb, c, MRB_TT_MODULE); - return mrb_class_ptr(c); -} - -static mrb_bool -class_ptr_p(mrb_value obj) -{ - switch (mrb_type(obj)) { - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - case MRB_TT_MODULE: - return TRUE; - default: - return FALSE; - } -} - -static void -check_if_class_or_module(mrb_state *mrb, mrb_value obj) -{ - if (!class_ptr_p(obj)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj)); - } -} - -static struct RClass* -define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer) -{ - struct RClass *m; - - if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { - return module_from_sym(mrb, outer, name); - } - m = mrb_module_new(mrb); - setup_class(mrb, outer, m, name); - - return m; -} - -MRB_API struct RClass* -mrb_define_module_id(mrb_state *mrb, mrb_sym name) -{ - return define_module(mrb, name, mrb->object_class); -} - -MRB_API struct RClass* -mrb_define_module(mrb_state *mrb, const char *name) -{ - return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class); -} - -MRB_API struct RClass* -mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id) -{ - check_if_class_or_module(mrb, outer); - if (mrb_const_defined_at(mrb, outer, id)) { - mrb_value old = mrb_const_get(mrb, outer, id); - - if (mrb_type(old) != MRB_TT_MODULE) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old)); - } - return mrb_class_ptr(old); - } - return define_module(mrb, id, mrb_class_ptr(outer)); -} - -MRB_API struct RClass* -mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - mrb_sym id = mrb_intern_cstr(mrb, name); - struct RClass * c = define_module(mrb, id, outer); - - setup_class(mrb, outer, c, id); - return c; -} - -static struct RClass* -find_origin(struct RClass *c) -{ - MRB_CLASS_ORIGIN(c); - return c; -} - -static struct RClass* -define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer) -{ - struct RClass * c; - - if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { - c = class_from_sym(mrb, outer, name); - MRB_CLASS_ORIGIN(c); - if (super && mrb_class_real(c->super) != super) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)", - mrb_sym2str(mrb, name), - mrb_obj_value(c->super), mrb_obj_value(super)); - } - return c; - } - - c = mrb_class_new(mrb, super); - setup_class(mrb, outer, c, name); - - return c; -} - -MRB_API struct RClass* -mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super) -{ - if (!super) { - mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name)); - } - return define_class(mrb, name, super, mrb->object_class); -} - -MRB_API struct RClass* -mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) -{ - return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super); -} - -static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value); -#ifdef MRB_METHOD_CACHE -static void mc_clear_all(mrb_state *mrb); -static void mc_clear_by_class(mrb_state *mrb, struct RClass*); -static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym); -#else -#define mc_clear_all(mrb) -#define mc_clear_by_class(mrb,c) -#define mc_clear_by_id(mrb,c,s) -#endif - -static void -mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass) -{ - mrb_value s; - mrb_sym mid; - - if (!super) - super = mrb->object_class; - super->flags |= MRB_FLAG_IS_INHERITED; - s = mrb_obj_value(super); - mc_clear_by_class(mrb, klass); - mid = mrb_intern_lit(mrb, "inherited"); - if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) { - mrb_value c = mrb_obj_value(klass); - mrb_funcall_argv(mrb, s, mid, 1, &c); - } -} - -MRB_API struct RClass* -mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id) -{ - struct RClass *s; - struct RClass *c; - - if (!mrb_nil_p(super)) { - if (mrb_type(super) != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", - mrb_inspect(mrb, super)); - } - s = mrb_class_ptr(super); - } - else { - s = 0; - } - check_if_class_or_module(mrb, outer); - if (mrb_const_defined_at(mrb, outer, id)) { - mrb_value old = mrb_const_get(mrb, outer, id); - - if (mrb_type(old) != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old)); - } - c = mrb_class_ptr(old); - if (s) { - /* check super class */ - if (mrb_class_real(c->super) != s) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old); - } - } - return c; - } - c = define_class(mrb, id, s, mrb_class_ptr(outer)); - mrb_class_inherited(mrb, mrb_class_real(c->super), c); - - return c; -} - -MRB_API mrb_bool -mrb_class_defined(mrb_state *mrb, const char *name) -{ - mrb_value sym = mrb_check_intern_cstr(mrb, name); - if (mrb_nil_p(sym)) { - return FALSE; - } - return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_symbol(sym)); -} - -MRB_API mrb_bool -mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - mrb_value sym = mrb_check_intern_cstr(mrb, name); - if (mrb_nil_p(sym)) { - return FALSE; - } - return mrb_const_defined_at(mrb, mrb_obj_value(outer), mrb_symbol(sym)); -} - -MRB_API struct RClass* -mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name)); -} - -MRB_API struct RClass* -mrb_class_get(mrb_state *mrb, const char *name) -{ - return mrb_class_get_under(mrb, mrb->object_class, name); -} - -MRB_API struct RClass* -mrb_exc_get(mrb_state *mrb, const char *name) -{ - struct RClass *exc, *e; - mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), - mrb_intern_cstr(mrb, name)); - - if (mrb_type(c) != MRB_TT_CLASS) { - mrb_raise(mrb, mrb->eException_class, "exception corrupted"); - } - exc = e = mrb_class_ptr(c); - - while (e) { - if (e == mrb->eException_class) - return exc; - e = e->super; - } - return mrb->eException_class; -} - -MRB_API struct RClass* -mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name)); -} - -MRB_API struct RClass* -mrb_module_get(mrb_state *mrb, const char *name) -{ - return mrb_module_get_under(mrb, mrb->object_class, name); -} - -/*! - * Defines a class under the namespace of \a outer. - * \param outer a class which contains the new class. - * \param id name of the new class - * \param super a class from which the new class will derive. - * NULL means \c Object class. - * \return the created class - * \throw TypeError if the constant name \a name is already taken but - * the constant is not a \c Class. - * \throw NameError if the class is already defined but the class can not - * be reopened because its superclass is not \a super. - * \post top-level constant named \a name refers the returned class. - * - * \note if a class named \a name is already defined and its superclass is - * \a super, the function just returns the defined class. - */ -MRB_API struct RClass* -mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super) -{ - mrb_sym id = mrb_intern_cstr(mrb, name); - struct RClass * c; - -#if 0 - if (!super) { - mrb_warn(mrb, "no super class for '%S::%S', Object assumed", - mrb_obj_value(outer), mrb_sym2str(mrb, id)); - } -#endif - c = define_class(mrb, id, super, outer); - setup_class(mrb, outer, c, id); - return c; -} - -MRB_API void -mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p) -{ - khash_t(mt) *h; - khiter_t k; - MRB_CLASS_ORIGIN(c); - h = c->mt; - - if (MRB_FROZEN_P(c)) { - if (c->tt == MRB_TT_MODULE) - mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen module"); - else - mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen class"); - } - if (!h) h = c->mt = kh_init(mt, mrb); - k = kh_put(mt, mrb, h, mid); - kh_value(h, k) = p; - if (p) { - p->c = NULL; - mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p); - } - mc_clear_by_id(mrb, c, mid); -} - -MRB_API void -mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec) -{ - struct RProc *p; - int ai = mrb_gc_arena_save(mrb); - - p = mrb_proc_new_cfunc(mrb, func); - p->target_class = c; - mrb_define_method_raw(mrb, c, mid, p); - mrb_gc_arena_restore(mrb, ai); -} - -MRB_API void -mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec); -} - -/* a function to raise NotImplementedError with current method name */ -MRB_API void -mrb_notimplement(mrb_state *mrb) -{ - const char *str; - mrb_int len; - mrb_callinfo *ci = mrb->c->ci; - - if (ci->mid) { - str = mrb_sym2name_len(mrb, ci->mid, &len); - mrb_raisef(mrb, E_NOTIMP_ERROR, - "%S() function is unimplemented on this machine", - mrb_str_new_static(mrb, str, (size_t)len)); - } -} - -/* a function to be replacement of unimplemented method */ -MRB_API mrb_value -mrb_notimplement_m(mrb_state *mrb, mrb_value self) -{ - mrb_notimplement(mrb); - /* not reached */ - return mrb_nil_value(); -} - -static mrb_value -check_type(mrb_state *mrb, mrb_value val, enum mrb_vtype t, const char *c, const char *m) -{ - mrb_value tmp; - - tmp = mrb_check_convert_type(mrb, val, t, c, m); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_cstr(mrb, c)); - } - return tmp; -} - -static mrb_value -to_str(mrb_state *mrb, mrb_value val) -{ - return check_type(mrb, val, MRB_TT_STRING, "String", "to_str"); -} - -static mrb_value -to_ary(mrb_state *mrb, mrb_value val) -{ - return check_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); -} - -static mrb_value -to_hash(mrb_state *mrb, mrb_value val) -{ - return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash"); -} - -static mrb_sym -to_sym(mrb_state *mrb, mrb_value ss) -{ - if (mrb_type(ss) == MRB_TT_SYMBOL) { - return mrb_symbol(ss); - } - else if (mrb_string_p(ss)) { - return mrb_intern_str(mrb, to_str(mrb, ss)); - } - else { - mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); - /* not reached */ - return 0; - } -} - -/* - retrieve arguments from mrb_state. - - mrb_get_args(mrb, format, ...) - - returns number of arguments parsed. - - format specifiers: - - string mruby type C type note - ---------------------------------------------------------------------------------------------- - o: Object [mrb_value] - C: class/module [mrb_value] - S: String [mrb_value] when ! follows, the value may be nil - A: Array [mrb_value] when ! follows, the value may be nil - H: Hash [mrb_value] when ! follows, the value may be nil - s: String [char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil - z: String [char*] NUL terminated string; z! gives NULL for nil - a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil - f: Float [mrb_float] - i: Integer [mrb_int] - b: Boolean [mrb_bool] - n: Symbol [mrb_sym] - d: Data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified - I: Inline struct [void*] - &: Block [mrb_value] - *: rest argument [mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack - |: optional Following arguments are optional - ?: optional given [mrb_bool] true if preceding argument (optional) is given - */ -MRB_API mrb_int -mrb_get_args(mrb_state *mrb, const char *format, ...) -{ - const char *fmt = format; - char c; - int i = 0; - va_list ap; - int argc = mrb->c->ci->argc; - int arg_i = 0; - mrb_value *array_argv; - mrb_bool opt = FALSE; - mrb_bool opt_skip = TRUE; - mrb_bool given = TRUE; - - va_start(ap, format); - if (argc < 0) { - struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); - - argc = ARY_LEN(a); - array_argv = ARY_PTR(a); - } - else { - array_argv = NULL; - } - -#define ARGV \ - (array_argv ? array_argv : (mrb->c->stack + 1)) - - while ((c = *fmt++)) { - switch (c) { - case '|': - opt = TRUE; - break; - case '*': - opt_skip = FALSE; - goto check_exit; - case '!': - break; - case '&': case '?': - if (opt) opt_skip = FALSE; - break; - default: - break; - } - } - - check_exit: - opt = FALSE; - i = 0; - while ((c = *format++)) { - switch (c) { - case '|': case '*': case '&': case '?': - break; - default: - if (argc <= i) { - if (opt) { - given = FALSE; - } - else { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); - } - } - break; - } - - switch (c) { - case 'o': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - *p = ARGV[arg_i++]; - i++; - } - } - break; - case 'C': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - mrb_value ss; - - ss = ARGV[arg_i++]; - if (!class_ptr_p(ss)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss); - } - *p = ss; - i++; - } - } - break; - case 'S': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *p = ARGV[arg_i++]; - i++; - break; - } - } - if (i < argc) { - *p = to_str(mrb, ARGV[arg_i++]); - i++; - } - } - break; - case 'A': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *p = ARGV[arg_i++]; - i++; - break; - } - } - if (i < argc) { - *p = to_ary(mrb, ARGV[arg_i++]); - i++; - } - } - break; - case 'H': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *p = ARGV[arg_i++]; - i++; - break; - } - } - if (i < argc) { - *p = to_hash(mrb, ARGV[arg_i++]); - i++; - } - } - break; - case 's': - { - mrb_value ss; - char **ps = 0; - mrb_int *pl = 0; - - ps = va_arg(ap, char**); - pl = va_arg(ap, mrb_int*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *ps = NULL; - *pl = 0; - i++; arg_i++; - break; - } - } - if (i < argc) { - ss = to_str(mrb, ARGV[arg_i++]); - *ps = RSTRING_PTR(ss); - *pl = RSTRING_LEN(ss); - i++; - } - } - break; - case 'z': - { - mrb_value ss; - const char **ps; - - ps = va_arg(ap, const char**); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *ps = NULL; - i++; arg_i++; - break; - } - } - if (i < argc) { - ss = to_str(mrb, ARGV[arg_i++]); - *ps = mrb_string_value_cstr(mrb, &ss); - i++; - } - } - break; - case 'a': - { - mrb_value aa; - struct RArray *a; - mrb_value **pb; - mrb_int *pl; - - pb = va_arg(ap, mrb_value**); - pl = va_arg(ap, mrb_int*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *pb = 0; - *pl = 0; - i++; arg_i++; - break; - } - } - if (i < argc) { - aa = to_ary(mrb, ARGV[arg_i++]); - a = mrb_ary_ptr(aa); - *pb = ARY_PTR(a); - *pl = ARY_LEN(a); - i++; - } - } - break; - case 'I': - { - void* *p; - mrb_value ss; - - p = va_arg(ap, void**); - if (i < argc) { - ss = ARGV[arg_i]; - if (mrb_type(ss) != MRB_TT_ISTRUCT) - { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss); - } - *p = mrb_istruct_ptr(ss); - arg_i++; - i++; - } - } - break; - case 'f': - { - mrb_float *p; - - p = va_arg(ap, mrb_float*); - if (i < argc) { - *p = mrb_to_flo(mrb, ARGV[arg_i]); - arg_i++; - i++; - } - } - break; - case 'i': - { - mrb_int *p; - - p = va_arg(ap, mrb_int*); - if (i < argc) { - switch (mrb_type(ARGV[arg_i])) { - case MRB_TT_FIXNUM: - *p = mrb_fixnum(ARGV[arg_i]); - break; - case MRB_TT_FLOAT: - { - mrb_float f = mrb_float(ARGV[arg_i]); - - if (!FIXABLE_FLOAT(f)) { - mrb_raise(mrb, E_RANGE_ERROR, "float too big for int"); - } - *p = (mrb_int)f; - } - break; - case MRB_TT_STRING: - mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer"); - break; - default: - *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i])); - break; - } - arg_i++; - i++; - } - } - break; - case 'b': - { - mrb_bool *boolp = va_arg(ap, mrb_bool*); - - if (i < argc) { - mrb_value b = ARGV[arg_i++]; - *boolp = mrb_test(b); - i++; - } - } - break; - case 'n': - { - mrb_sym *symp; - - symp = va_arg(ap, mrb_sym*); - if (i < argc) { - mrb_value ss; - - ss = ARGV[arg_i++]; - *symp = to_sym(mrb, ss); - i++; - } - } - break; - case 'd': - { - void** datap; - struct mrb_data_type const* type; - - datap = va_arg(ap, void**); - type = va_arg(ap, struct mrb_data_type const*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *datap = 0; - i++; arg_i++; - break; - } - } - if (i < argc) { - *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type); - ++i; - } - } - break; - - case '&': - { - mrb_value *p, *bp; - - p = va_arg(ap, mrb_value*); - if (mrb->c->ci->argc < 0) { - bp = mrb->c->stack + 2; - } - else { - bp = mrb->c->stack + mrb->c->ci->argc + 1; - } - *p = *bp; - } - break; - case '|': - if (opt_skip && i == argc) return argc; - opt = TRUE; - break; - case '?': - { - mrb_bool *p; - - p = va_arg(ap, mrb_bool*); - *p = given; - } - break; - - case '*': - { - mrb_value **var; - mrb_int *pl; - mrb_bool nocopy = array_argv ? TRUE : FALSE; - - if (*format == '!') { - format++; - nocopy = TRUE; - } - var = va_arg(ap, mrb_value**); - pl = va_arg(ap, mrb_int*); - if (argc > i) { - *pl = argc-i; - if (*pl > 0) { - if (nocopy) { - *var = ARGV+arg_i; - } - else { - mrb_value args = mrb_ary_new_from_values(mrb, *pl, ARGV+arg_i); - RARRAY(args)->c = NULL; - *var = RARRAY_PTR(args); - } - } - i = argc; - arg_i += *pl; - } - else { - *pl = 0; - *var = NULL; - } - } - break; - default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1)); - break; - } - } - -#undef ARGV - - if (!c && argc > i) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); - } - va_end(ap); - return i; -} - -static struct RClass* -boot_defclass(mrb_state *mrb, struct RClass *super) -{ - struct RClass *c; - - c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class); - if (super) { - c->super = super; - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); - } - else { - c->super = mrb->object_class; - } - c->mt = kh_init(mt, mrb); - return c; -} - -static void -boot_initmod(mrb_state *mrb, struct RClass *mod) -{ - if (!mod->mt) { - mod->mt = kh_init(mt, mrb); - } -} - -static struct RClass* -include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) -{ - struct RClass *ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); - if (m->tt == MRB_TT_ICLASS) { - m = m->c; - } - MRB_CLASS_ORIGIN(m); - ic->iv = m->iv; - ic->mt = m->mt; - ic->super = super; - if (m->tt == MRB_TT_ICLASS) { - ic->c = m->c; - } - else { - ic->c = m; - } - return ic; -} - -static int -include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) -{ - struct RClass *p, *ic; - void *klass_mt = find_origin(c)->mt; - - while (m) { - int superclass_seen = 0; - - if (m->flags & MRB_FLAG_IS_PREPENDED) - goto skip; - - if (klass_mt && klass_mt == m->mt) - return -1; - - p = c->super; - while (p) { - if (p->tt == MRB_TT_ICLASS) { - if (p->mt == m->mt) { - if (!superclass_seen) { - ins_pos = p; /* move insert point */ - } - goto skip; - } - } else if (p->tt == MRB_TT_CLASS) { - if (!search_super) break; - superclass_seen = 1; - } - p = p->super; - } - - ic = include_class_new(mrb, m, ins_pos->super); - m->flags |= MRB_FLAG_IS_INHERITED; - ins_pos->super = ic; - mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic); - mc_clear_by_class(mrb, ins_pos); - ins_pos = ic; - skip: - m = m->super; - } - mc_clear_all(mrb); - return 0; -} - -MRB_API void -mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) -{ - int changed = include_module_at(mrb, c, find_origin(c), m, 1); - if (changed < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); - } -} - -MRB_API void -mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) -{ - struct RClass *origin; - int changed = 0; - - if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { - origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); - origin->flags |= MRB_FLAG_IS_ORIGIN | MRB_FLAG_IS_INHERITED; - origin->super = c->super; - c->super = origin; - origin->mt = c->mt; - c->mt = kh_init(mt, mrb); - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin); - c->flags |= MRB_FLAG_IS_PREPENDED; - } - changed = include_module_at(mrb, c, c, m, 0); - if (changed < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected"); - } -} - -static mrb_value -mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod) -{ - mrb_value klass; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "C", &klass); - mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); - return mod; -} - -static mrb_value -mrb_mod_append_features(mrb_state *mrb, mrb_value mod) -{ - mrb_value klass; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "C", &klass); - mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); - return mod; -} - -/* 15.2.2.4.28 */ -/* - * call-seq: - * mod.include?(module) -> true or false - * - * Returns <code>true</code> if <i>module</i> is included in - * <i>mod</i> or one of <i>mod</i>'s ancestors. - * - * module A - * end - * class B - * include A - * end - * class C < B - * end - * B.include?(A) #=> true - * C.include?(A) #=> true - * A.include?(A) #=> false - */ -static mrb_value -mrb_mod_include_p(mrb_state *mrb, mrb_value mod) -{ - mrb_value mod2; - struct RClass *c = mrb_class_ptr(mod); - - mrb_get_args(mrb, "C", &mod2); - mrb_check_type(mrb, mod2, MRB_TT_MODULE); - - while (c) { - if (c->tt == MRB_TT_ICLASS) { - if (c->c == mrb_class_ptr(mod2)) return mrb_true_value(); - } - c = c->super; - } - return mrb_false_value(); -} - -static mrb_value -mrb_mod_ancestors(mrb_state *mrb, mrb_value self) -{ - mrb_value result; - struct RClass *c = mrb_class_ptr(self); - result = mrb_ary_new(mrb); - while (c) { - if (c->tt == MRB_TT_ICLASS) { - mrb_ary_push(mrb, result, mrb_obj_value(c->c)); - } - else if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { - mrb_ary_push(mrb, result, mrb_obj_value(c)); - } - c = c->super; - } - - return result; -} - -static mrb_value -mrb_mod_extend_object(mrb_state *mrb, mrb_value mod) -{ - mrb_value obj; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "o", &obj); - mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod)); - return mod; -} - -static mrb_value -mrb_mod_included_modules(mrb_state *mrb, mrb_value self) -{ - mrb_value result; - struct RClass *c = mrb_class_ptr(self); - struct RClass *origin = c; - - MRB_CLASS_ORIGIN(origin); - result = mrb_ary_new(mrb); - while (c) { - if (c != origin && c->tt == MRB_TT_ICLASS) { - if (c->c->tt == MRB_TT_MODULE) { - mrb_ary_push(mrb, result, mrb_obj_value(c->c)); - } - } - c = c->super; - } - - return result; -} - -static mrb_value -mrb_mod_initialize(mrb_state *mrb, mrb_value mod) -{ - mrb_value b; - struct RClass *m = mrb_class_ptr(mod); - boot_initmod(mrb, m); /* bootstrap a newly initialized module */ - mrb_get_args(mrb, "|&", &b); - if (!mrb_nil_p(b)) { - mrb_yield_with_class(mrb, b, 1, &mod, mod, m); - } - return mod; -} - -mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int); - -/* 15.2.2.4.33 */ -/* - * call-seq: - * mod.instance_methods(include_super=true) -> array - * - * Returns an array containing the names of the public and protected instance - * methods in the receiver. For a module, these are the public and protected methods; - * for a class, they are the instance (not singleton) methods. With no - * argument, or with an argument that is <code>false</code>, the - * instance methods in <i>mod</i> are returned, otherwise the methods - * in <i>mod</i> and <i>mod</i>'s superclasses are returned. - * - * module A - * def method1() end - * end - * class B - * def method2() end - * end - * class C < B - * def method3() end - * end - * - * A.instance_methods #=> [:method1] - * B.instance_methods(false) #=> [:method2] - * C.instance_methods(false) #=> [:method3] - * C.instance_methods(true).length #=> 43 - */ - -static mrb_value -mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_class_instance_method_list(mrb, recur, c, 0); -} - -/* implementation of module_eval/class_eval */ -mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); - -static mrb_value -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) -{ - 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); - case MRB_TT_TRUE: - return mrb_obj_value(mrb->true_class); - case MRB_TT_CPTR: - return mrb_obj_value(mrb->object_class); - case MRB_TT_SYMBOL: - case MRB_TT_FIXNUM: - case MRB_TT_FLOAT: - mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton"); - return mrb_nil_value(); /* not reached */ - default: - break; - } - obj = mrb_basic_ptr(v); - prepare_singleton_class(mrb, obj); - return mrb_obj_value(obj->c); -} - -MRB_API void -mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - prepare_singleton_class(mrb, (struct RBasic*)o); - mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec); -} - -MRB_API void -mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec); -} - -MRB_API void -mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - mrb_define_class_method(mrb, c, name, func, aspec); - mrb_define_method(mrb, c, name, func, aspec); -} - -#ifdef MRB_METHOD_CACHE -static void -mc_clear_all(mrb_state *mrb) -{ - struct mrb_cache_entry *mc = mrb->cache; - int i; - - for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { - mc[i].c = 0; - } -} - -static void -mc_clear_by_class(mrb_state *mrb, struct RClass *c) -{ - struct mrb_cache_entry *mc = mrb->cache; - int i; - - if (c->flags & MRB_FLAG_IS_INHERITED) { - mc_clear_all(mrb); - c->flags &= ~MRB_FLAG_IS_INHERITED; - return; - } - for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { - if (mc[i].c == c) mc[i].c = 0; - } -} - -static void -mc_clear_by_id(mrb_state *mrb, struct RClass *c, mrb_sym mid) -{ - struct mrb_cache_entry *mc = mrb->cache; - int i; - - if (c->flags & MRB_FLAG_IS_INHERITED) { - mc_clear_all(mrb); - c->flags &= ~MRB_FLAG_IS_INHERITED; - return; - } - for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { - if (mc[i].c == c || mc[i].mid == mid) - mc[i].c = 0; - } -} -#endif - -MRB_API struct RProc* -mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) -{ - khiter_t k; - struct RProc *m; - struct RClass *c = *cp; -#ifdef MRB_METHOD_CACHE - struct RClass *oc = c; - int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1); - struct mrb_cache_entry *mc = &mrb->cache[h]; - - if (mc->c == c && mc->mid == mid) { - return mc->m; - } -#endif - - while (c) { - khash_t(mt) *h = c->mt; - - if (h) { - k = kh_get(mt, mrb, h, mid); - if (k != kh_end(h)) { - m = kh_value(h, k); - if (!m) break; - *cp = c; -#ifdef MRB_METHOD_CACHE - mc->c = oc; - mc->mid = mid; - mc->m = m; -#endif - return m; - } - } - c = c->super; - } - return NULL; /* no method */ -} - -MRB_API struct RProc* -mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) -{ - struct RProc *m; - - m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { - mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0); - if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) { - inspect = mrb_any_to_s(mrb, mrb_obj_value(c)); - } - mrb_name_error(mrb, mid, "undefined method '%S' for class %S", - mrb_sym2str(mrb, mid), inspect); - } - return m; -} - -static mrb_value -attr_reader(mrb_state *mrb, mrb_value obj) -{ - mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); - return mrb_iv_get(mrb, obj, to_sym(mrb, name)); -} - -static mrb_value -mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_value *argv; - mrb_int argc, i; - int ai; - - mrb_get_args(mrb, "*", &argv, &argc); - ai = mrb_gc_arena_save(mrb); - for (i=0; i<argc; i++) { - mrb_value name, str; - mrb_sym method, sym; - - method = to_sym(mrb, argv[i]); - name = mrb_sym2str(mrb, method); - str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1); - mrb_str_cat_lit(mrb, str, "@"); - mrb_str_cat_str(mrb, str, name); - sym = mrb_intern_str(mrb, str); - mrb_iv_check(mrb, sym); - name = mrb_symbol_value(sym); - mrb_define_method_raw(mrb, c, method, - mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name)); - mrb_gc_arena_restore(mrb, ai); - } - return mrb_nil_value(); -} - -static mrb_value -attr_writer(mrb_state *mrb, mrb_value obj) -{ - mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); - mrb_value val; - - mrb_get_args(mrb, "o", &val); - mrb_iv_set(mrb, obj, to_sym(mrb, name), val); - return val; -} - -static mrb_value -mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_value *argv; - mrb_int argc, i; - int ai; - - mrb_get_args(mrb, "*", &argv, &argc); - ai = mrb_gc_arena_save(mrb); - for (i=0; i<argc; i++) { - mrb_value name, str, attr; - mrb_sym method, sym; - - method = to_sym(mrb, argv[i]); - - /* prepare iv name (@name) */ - name = mrb_sym2str(mrb, method); - str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1); - mrb_str_cat_lit(mrb, str, "@"); - mrb_str_cat_str(mrb, str, name); - sym = mrb_intern_str(mrb, str); - mrb_iv_check(mrb, sym); - attr = mrb_symbol_value(sym); - - /* prepare method name (name=) */ - str = mrb_str_new_capa(mrb, RSTRING_LEN(str)); - mrb_str_cat_str(mrb, str, name); - mrb_str_cat_lit(mrb, str, "="); - method = mrb_intern_str(mrb, str); - - mrb_define_method_raw(mrb, c, method, - mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr)); - mrb_gc_arena_restore(mrb, ai); - } - return mrb_nil_value(); -} - -static mrb_value -mrb_instance_alloc(mrb_state *mrb, mrb_value cv) -{ - struct RClass *c = mrb_class_ptr(cv); - struct RObject *o; - enum mrb_vtype ttype = MRB_INSTANCE_TT(c); - - if (c->tt == MRB_TT_SCLASS) - mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class"); - - if (ttype == 0) ttype = MRB_TT_OBJECT; - if (ttype <= MRB_TT_CPTR) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv); - } - o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c); - return mrb_obj_value(o); -} - -/* - * call-seq: - * class.new(args, ...) -> obj - * - * Creates a new object of <i>class</i>'s class, then - * invokes that object's <code>initialize</code> method, - * passing it <i>args</i>. This is the method that ends - * up getting called whenever an object is constructed using - * `.new`. - * - */ - -MRB_API mrb_value -mrb_instance_new(mrb_state *mrb, mrb_value cv) -{ - mrb_value obj, blk; - mrb_value *argv; - mrb_int argc; - mrb_sym init; - - mrb_get_args(mrb, "*&", &argv, &argc, &blk); - obj = mrb_instance_alloc(mrb, cv); - init = mrb_intern_lit(mrb, "initialize"); - if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) { - mrb_funcall_with_block(mrb, obj, init, argc, argv, blk); - } - - return obj; -} - -MRB_API mrb_value -mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv) -{ - mrb_value obj; - mrb_sym mid; - - obj = mrb_instance_alloc(mrb, mrb_obj_value(c)); - mid = mrb_intern_lit(mrb, "initialize"); - if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) { - mrb_funcall_argv(mrb, obj, mid, argc, argv); - } - return obj; -} - -static mrb_value -mrb_class_initialize(mrb_state *mrb, mrb_value c) -{ - mrb_value a, b; - - mrb_get_args(mrb, "|C&", &a, &b); - if (!mrb_nil_p(b)) { - mrb_yield_with_class(mrb, b, 1, &c, c, mrb_class_ptr(c)); - } - return c; -} - -static mrb_value -mrb_class_new_class(mrb_state *mrb, mrb_value cv) -{ - mrb_int n; - mrb_value super, blk; - mrb_value new_class; - mrb_sym mid; - - n = mrb_get_args(mrb, "|C&", &super, &blk); - if (n == 0) { - super = mrb_obj_value(mrb->object_class); - } - new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super))); - mid = mrb_intern_lit(mrb, "initialize"); - if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) { - mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk); - } - mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class)); - return new_class; -} - -static mrb_value -mrb_class_superclass(mrb_state *mrb, mrb_value klass) -{ - struct RClass *c; - - c = mrb_class_ptr(klass); - c = find_origin(c)->super; - while (c && c->tt == MRB_TT_ICLASS) { - c = find_origin(c)->super; - } - if (!c) return mrb_nil_value(); - return mrb_obj_value(c); -} - -static mrb_value -mrb_bob_init(mrb_state *mrb, mrb_value cv) -{ - return mrb_nil_value(); -} - -static mrb_value -mrb_bob_not(mrb_state *mrb, mrb_value cv) -{ - return mrb_bool_value(!mrb_test(cv)); -} - -/* 15.3.1.3.1 */ -/* 15.3.1.3.10 */ -/* 15.3.1.3.11 */ -/* - * call-seq: - * obj == other -> true or false - * obj.equal?(other) -> true or false - * obj.eql?(other) -> true or false - * - * Equality---At the <code>Object</code> level, <code>==</code> returns - * <code>true</code> only if <i>obj</i> and <i>other</i> are the - * same object. Typically, this method is overridden in descendant - * classes to provide class-specific meaning. - * - * Unlike <code>==</code>, the <code>equal?</code> method should never be - * overridden by subclasses: it is used to determine object identity - * (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same - * object as <code>b</code>). - * - * The <code>eql?</code> method returns <code>true</code> if - * <i>obj</i> and <i>anObject</i> have the same value. Used by - * <code>Hash</code> to test members for equality. For objects of - * class <code>Object</code>, <code>eql?</code> is synonymous with - * <code>==</code>. Subclasses normally continue this tradition, but - * there are exceptions. <code>Numeric</code> types, for example, - * perform type conversion across <code>==</code>, but not across - * <code>eql?</code>, so: - * - * 1 == 1.0 #=> true - * 1.eql? 1.0 #=> false - */ -mrb_value -mrb_obj_equal_m(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "o", &arg); - 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_get_args(mrb, "o", &arg); - return mrb_bool_value(!mrb_equal(mrb, self, arg)); -} - -MRB_API mrb_bool -mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid) -{ - struct RProc *m; - - m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { - return FALSE; - } - return TRUE; -} - -MRB_API mrb_bool -mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid) -{ - return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid); -} - -MRB_API mrb_value -mrb_class_path(mrb_state *mrb, struct RClass *c) -{ - mrb_value path; - mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); - - path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym); - if (mrb_nil_p(path)) { - /* no name (yet) */ - return mrb_class_find_path(mrb, c); - } - else if (mrb_symbol_p(path)) { - /* topleve class/module */ - const char *str; - mrb_int len; - - str = mrb_sym2name_len(mrb, mrb_symbol(path), &len); - return mrb_str_new(mrb, str, len); - } - return mrb_str_dup(mrb, path); -} - -MRB_API struct RClass* -mrb_class_real(struct RClass* cl) -{ - if (cl == 0) - return NULL; - while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) { - cl = cl->super; - } - return cl; -} - -MRB_API const char* -mrb_class_name(mrb_state *mrb, struct RClass* c) -{ - mrb_value path = mrb_class_path(mrb, c); - if (mrb_nil_p(path)) { - path = mrb_str_new_lit(mrb, "#<Class:"); - mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c)); - mrb_str_cat_lit(mrb, path, ">"); - } - return RSTRING_PTR(path); -} - -MRB_API const char* -mrb_obj_classname(mrb_state *mrb, mrb_value obj) -{ - return mrb_class_name(mrb, mrb_obj_class(mrb, obj)); -} - -/*! - * Ensures a class can be derived from super. - * - * \param super a reference to an object. - * \exception TypeError if \a super is not a Class or \a super is a singleton class. - */ -static void -mrb_check_inheritable(mrb_state *mrb, struct RClass *super) -{ - if (super->tt != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super)); - } - if (super->tt == MRB_TT_SCLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class"); - } - if (super == mrb->class_class) { - mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class"); - } -} - -/*! - * Creates a new class. - * \param super a class from which the new class derives. - * \exception TypeError \a super is not inheritable. - * \exception TypeError \a super is the Class class. - */ -MRB_API struct RClass* -mrb_class_new(mrb_state *mrb, struct RClass *super) -{ - struct RClass *c; - - if (super) { - mrb_check_inheritable(mrb, super); - } - c = boot_defclass(mrb, super); - if (super) { - MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super)); - } - make_metaclass(mrb, c); - - return c; -} - -/*! - * Creates a new module. - */ -MRB_API struct RClass* -mrb_module_new(mrb_state *mrb) -{ - struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class); - boot_initmod(mrb, m); - return m; -} - -/* - * call-seq: - * obj.class => class - * - * Returns the class of <i>obj</i>, now preferred over - * <code>Object#type</code>, as an object's type in Ruby is only - * loosely tied to that object's class. This method must always be - * called with an explicit receiver, as <code>class</code> is also a - * reserved word in Ruby. - * - * 1.class #=> Fixnum - * self.class #=> Object - */ - -MRB_API struct RClass* -mrb_obj_class(mrb_state *mrb, mrb_value obj) -{ - return mrb_class_real(mrb_class(mrb, obj)); -} - -MRB_API void -mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) -{ - struct RProc *m = mrb_method_search(mrb, c, b); - - mrb_define_method_raw(mrb, c, a, m); -} - -/*! - * Defines an alias of a method. - * \param klass the class which the original method belongs to - * \param name1 a new name for the method - * \param name2 the original name of the method - */ -MRB_API void -mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2) -{ - mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2)); -} - -/* - * call-seq: - * mod.to_s -> string - * - * Return a string representing this module or class. For basic - * classes and modules, this is the name. For singletons, we - * show information on the thing we're attached to as well. - */ - -static mrb_value -mrb_mod_to_s(mrb_state *mrb, mrb_value klass) -{ - mrb_value str; - - if (mrb_type(klass) == MRB_TT_SCLASS) { - mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__")); - - str = mrb_str_new_lit(mrb, "#<Class:"); - - if (class_ptr_p(v)) { - mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v)); - } - else { - mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v)); - } - return mrb_str_cat_lit(mrb, str, ">"); - } - else { - struct RClass *c; - mrb_value path; - - str = mrb_str_new_capa(mrb, 32); - c = mrb_class_ptr(klass); - path = mrb_class_path(mrb, c); - - if (mrb_nil_p(path)) { - switch (mrb_type(klass)) { - case MRB_TT_CLASS: - mrb_str_cat_lit(mrb, str, "#<Class:"); - break; - - case MRB_TT_MODULE: - mrb_str_cat_lit(mrb, str, "#<Module:"); - break; - - default: - /* Shouldn't be happened? */ - mrb_str_cat_lit(mrb, str, "#<??????:"); - break; - } - mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c)); - return mrb_str_cat_lit(mrb, str, ">"); - } - else { - return path; - } - } -} - -static mrb_value -mrb_mod_alias(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_sym new_name, old_name; - - mrb_get_args(mrb, "nn", &new_name, &old_name); - mrb_alias_method(mrb, c, new_name, old_name); - return mrb_nil_value(); -} - -static void -undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a) -{ - if (!mrb_obj_respond_to(mrb, c, a)) { - mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c)); - } - else { - mrb_define_method_raw(mrb, c, a, NULL); - } -} - -MRB_API void -mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name) -{ - undef_method(mrb, c, mrb_intern_cstr(mrb, name)); -} - -MRB_API void -mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name) -{ - mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name); -} - -static mrb_value -mrb_mod_undef(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_int argc; - mrb_value *argv; - - mrb_get_args(mrb, "*", &argv, &argc); - while (argc--) { - undef_method(mrb, c, to_sym(mrb, *argv)); - argv++; - } - return mrb_nil_value(); -} - -static mrb_value -mod_define_method(mrb_state *mrb, mrb_value self) -{ - struct RClass *c = mrb_class_ptr(self); - struct RProc *p; - mrb_sym mid; - mrb_value proc = mrb_undef_value(); - mrb_value blk; - - mrb_get_args(mrb, "n|o&", &mid, &proc, &blk); - switch (mrb_type(proc)) { - case MRB_TT_PROC: - blk = proc; - break; - case MRB_TT_UNDEF: - /* ignored */ - break; - default: - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc))); - break; - } - if (mrb_nil_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); - mrb_proc_copy(p, mrb_proc_ptr(blk)); - p->flags |= MRB_PROC_STRICT; - mrb_define_method_raw(mrb, c, mid, p); - return mrb_symbol_value(mid); -} - -static void -check_cv_name_str(mrb_state *mrb, mrb_value str) -{ - const char *s = RSTRING_PTR(str); - mrb_int len = RSTRING_LEN(str); - - if (len < 3 || !(s[0] == '@' && s[1] == '@')) { - mrb_name_error(mrb, mrb_intern_str(mrb, str), "'%S' is not allowed as a class variable name", str); - } -} - -static void -check_cv_name_sym(mrb_state *mrb, mrb_sym id) -{ - check_cv_name_str(mrb, mrb_sym2str(mrb, id)); -} - -/* 15.2.2.4.16 */ -/* - * call-seq: - * obj.class_variable_defined?(symbol) -> true or false - * - * Returns <code>true</code> if the given class variable is defined - * in <i>obj</i>. - * - * class Fred - * @@foo = 99 - * end - * Fred.class_variable_defined?(:@@foo) #=> true - * Fred.class_variable_defined?(:@@bar) #=> false - */ - -static mrb_value -mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - check_cv_name_sym(mrb, id); - return mrb_bool_value(mrb_cv_defined(mrb, mod, id)); -} - -/* 15.2.2.4.17 */ -/* - * call-seq: - * mod.class_variable_get(symbol) -> obj - * - * Returns the value of the given class variable (or throws a - * <code>NameError</code> exception). The <code>@@</code> part of the - * variable name should be included for regular class variables - * - * class Fred - * @@foo = 99 - * end - * Fred.class_variable_get(:@@foo) #=> 99 - */ - -static mrb_value -mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - check_cv_name_sym(mrb, id); - return mrb_cv_get(mrb, mod, id); -} - -/* 15.2.2.4.18 */ -/* - * call-seq: - * obj.class_variable_set(symbol, obj) -> obj - * - * Sets the class variable names by <i>symbol</i> to - * <i>object</i>. - * - * class Fred - * @@foo = 99 - * def foo - * @@foo - * end - * end - * Fred.class_variable_set(:@@foo, 101) #=> 101 - * Fred.new.foo #=> 101 - */ - -static mrb_value -mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod) -{ - mrb_value value; - mrb_sym id; - - mrb_get_args(mrb, "no", &id, &value); - check_cv_name_sym(mrb, id); - mrb_cv_set(mrb, mod, id, value); - return value; -} - -/* 15.2.2.4.39 */ -/* - * call-seq: - * remove_class_variable(sym) -> obj - * - * Removes the definition of the <i>sym</i>, returning that - * constant's value. - * - * class Dummy - * @@var = 99 - * puts @@var - * p class_variables - * remove_class_variable(:@@var) - * p class_variables - * end - * - * <em>produces:</em> - * - * 99 - * [:@@var] - * [] - */ - -static mrb_value -mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) -{ - mrb_value val; - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - check_cv_name_sym(mrb, id); - - val = mrb_iv_remove(mrb, mod, id); - if (!mrb_undef_p(val)) return val; - - if (mrb_cv_defined(mrb, mod, id)) { - mrb_name_error(mrb, id, "cannot remove %S for %S", - mrb_sym2str(mrb, id), mod); - } - - mrb_name_error(mrb, id, "class variable %S not defined for %S", - mrb_sym2str(mrb, id), mod); - - /* not reached */ - return mrb_nil_value(); -} - -/* 15.2.2.4.34 */ -/* - * call-seq: - * mod.method_defined?(symbol) -> true or false - * - * Returns +true+ if the named method is defined by - * _mod_ (or its included modules and, if _mod_ is a class, - * its ancestors). Public and protected methods are matched. - * - * module A - * def method1() end - * end - * class B - * def method2() end - * end - * class C < B - * include A - * def method3() end - * end - * - * A.method_defined? :method1 #=> true - * C.method_defined? "method1" #=> true - * C.method_defined? "method2" #=> true - * C.method_defined? "method3" #=> true - * C.method_defined? "method4" #=> false - */ - -static mrb_value -mrb_mod_method_defined(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id)); -} - -static void -remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) -{ - struct RClass *c = mrb_class_ptr(mod); - khash_t(mt) *h = find_origin(c)->mt; - khiter_t k; - - if (h) { - k = kh_get(mt, mrb, h, mid); - if (k != kh_end(h)) { - kh_del(mt, mrb, h, k); - mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid)); - return; - } - } - - mrb_name_error(mrb, mid, "method '%S' not defined in %S", - mrb_sym2str(mrb, mid), mod); -} - -/* 15.2.2.4.41 */ -/* - * call-seq: - * remove_method(symbol) -> self - * - * Removes the method identified by _symbol_ from the current - * class. For an example, see <code>Module.undef_method</code>. - */ - -static mrb_value -mrb_mod_remove_method(mrb_state *mrb, mrb_value mod) -{ - mrb_int argc; - mrb_value *argv; - - mrb_get_args(mrb, "*", &argv, &argc); - while (argc--) { - remove_method(mrb, mod, to_sym(mrb, *argv)); - argv++; - } - return mod; -} - - - -static void -check_const_name_str(mrb_state *mrb, mrb_value str) -{ - if (RSTRING_LEN(str) < 1 || !ISUPPER(*RSTRING_PTR(str))) { - mrb_name_error(mrb, mrb_intern_str(mrb, str), "wrong constant name %S", str); - } -} - -static void -check_const_name_sym(mrb_state *mrb, mrb_sym id) -{ - check_const_name_str(mrb, mrb_sym2str(mrb, id)); -} - -static mrb_value -const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool inherit) -{ - if (inherit) { - return mrb_bool_value(mrb_const_defined(mrb, mod, id)); - } - return mrb_bool_value(mrb_const_defined_at(mrb, mod, id)); -} - -static mrb_value -mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - mrb_bool inherit = TRUE; - - mrb_get_args(mrb, "n|b", &id, &inherit); - check_const_name_sym(mrb, id); - return const_defined(mrb, mod, id, inherit); -} - -static mrb_value -mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id) -{ - check_const_name_sym(mrb, id); - return mrb_const_get(mrb, mod, id); -} - -static mrb_value -mrb_mod_const_get(mrb_state *mrb, mrb_value mod) -{ - mrb_value path; - mrb_sym id; - char *ptr; - mrb_int off, end, len; - - mrb_get_args(mrb, "o", &path); - - if (mrb_symbol_p(path)) { - /* const get with symbol */ - id = mrb_symbol(path); - return mrb_const_get_sym(mrb, mod, id); - } - - /* const get with class path string */ - path = mrb_string_type(mrb, path); - ptr = RSTRING_PTR(path); - len = RSTRING_LEN(path); - off = 0; - - while (off < len) { - end = mrb_str_index_lit(mrb, path, "::", off); - end = (end == -1) ? len : end; - id = mrb_intern(mrb, ptr+off, end-off); - mod = mrb_const_get_sym(mrb, mod, id); - off = (end == len) ? end : end+2; - } - - return mod; -} - -static mrb_value -mrb_mod_const_set(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - mrb_value value; - - mrb_get_args(mrb, "no", &id, &value); - check_const_name_sym(mrb, id); - mrb_const_set(mrb, mod, id, value); - return value; -} - -static mrb_value -mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - mrb_value val; - - mrb_get_args(mrb, "n", &id); - check_const_name_sym(mrb, id); - val = mrb_iv_remove(mrb, mod, id); - if (mrb_undef_p(val)) { - mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id)); - } - return val; -} - -static mrb_value -mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) -{ - mrb_sym sym; - - mrb_get_args(mrb, "n", &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(); -} - -static mrb_value -mrb_mod_s_constants(mrb_state *mrb, mrb_value mod) -{ - mrb_raise(mrb, E_NOTIMP_ERROR, "Module.constants not implemented"); - return mrb_nil_value(); /* not reached */ -} - -static mrb_value -mrb_mod_eqq(mrb_state *mrb, mrb_value mod) -{ - mrb_value obj; - mrb_bool eqq; - - mrb_get_args(mrb, "o", &obj); - eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod)); - - return mrb_bool_value(eqq); -} - -MRB_API mrb_value -mrb_mod_module_function(mrb_state *mrb, mrb_value mod) -{ - mrb_value *argv; - mrb_int argc, i; - mrb_sym mid; - struct RProc *method_rproc; - struct RClass *rclass; - int ai; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - - mrb_get_args(mrb, "*", &argv, &argc); - if (argc == 0) { - /* set MODFUNC SCOPE if implemented */ - return mod; - } - - /* set PRIVATE method visibility if implemented */ - /* mrb_mod_dummy_visibility(mrb, mod); */ - - for (i=0; i<argc; i++) { - mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL); - - mid = mrb_symbol(argv[i]); - rclass = mrb_class_ptr(mod); - method_rproc = mrb_method_search(mrb, rclass, mid); - - prepare_singleton_class(mrb, (struct RBasic*)rclass); - ai = mrb_gc_arena_save(mrb); - mrb_define_method_raw(mrb, rclass->c, mid, method_rproc); - mrb_gc_arena_restore(mrb, ai); - } - - return mod; -} - -/* implementation of __id__ */ -mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self); -/* implementation of instance_eval */ -mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value); -/* implementation of Module.nesting */ -mrb_value mrb_mod_s_nesting(mrb_state*, mrb_value); - -void -mrb_init_class(mrb_state *mrb) -{ - struct RClass *bob; /* BasicObject */ - struct RClass *obj; /* Object */ - struct RClass *mod; /* Module */ - struct RClass *cls; /* Class */ - - /* boot class hierarchy */ - bob = boot_defclass(mrb, 0); - obj = boot_defclass(mrb, bob); mrb->object_class = obj; - mod = boot_defclass(mrb, obj); mrb->module_class = mod;/* obj -> mod */ - cls = boot_defclass(mrb, mod); mrb->class_class = cls; /* obj -> cls */ - /* fix-up loose ends */ - bob->c = obj->c = mod->c = cls->c = cls; - make_metaclass(mrb, bob); - make_metaclass(mrb, obj); - make_metaclass(mrb, mod); - make_metaclass(mrb, cls); - - /* name basic classes */ - mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob)); - mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob)); - mrb_define_const(mrb, obj, "Object", mrb_obj_value(obj)); - mrb_define_const(mrb, obj, "Module", mrb_obj_value(mod)); - mrb_define_const(mrb, obj, "Class", mrb_obj_value(cls)); - - /* name each classes */ - mrb_class_name_class(mrb, NULL, bob, mrb_intern_lit(mrb, "BasicObject")); - mrb_class_name_class(mrb, NULL, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */ - mrb_class_name_class(mrb, NULL, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */ - mrb_class_name_class(mrb, NULL, cls, mrb_intern_lit(mrb, "Class")); /* 15.2.3 */ - - mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); /* 15.2.17 */ - MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); - - MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS); - mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE()); - mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE()); - mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */ - mrb_define_method(mrb, bob, "!=", mrb_obj_not_equal_m, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.3 */ - mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.4 */ - mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_ANY()); /* 15.3.1.3.18 */ - - mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */ - mrb_define_method(mrb, cls, "new", mrb_instance_new, MRB_ARGS_ANY()); /* 15.2.3.3.3 */ - mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */ - mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1)); - - MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE); - mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.16 */ - mrb_define_method(mrb, mod, "class_variable_get", mrb_mod_cvar_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.17 */ - mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */ - mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */ - mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ - mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */ - mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */ - mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */ - mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ - mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */ - mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */ - mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */ - mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */ - mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */ - mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY()); - mrb_define_method(mrb, mod, "private", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */ - mrb_define_method(mrb, mod, "protected", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */ - mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */ - mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */ - mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ - mrb_define_method(mrb, mod, "method_removed", mrb_bob_init, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */ - mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */ - mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, mod, "inspect", mrb_mod_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */ - mrb_define_method(mrb, mod, "ancestors", mrb_mod_ancestors, MRB_ARGS_NONE()); /* 15.2.2.4.9 */ - mrb_define_method(mrb, mod, "undef_method", mrb_mod_undef, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ - mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, MRB_ARGS_ARG(1,1)); /* 15.2.2.4.20 */ - mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */ - mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */ - mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */ - mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */ - mrb_define_method(mrb, mod, "const_missing", mrb_mod_const_missing, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1)); - mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_NONE()); /* 15.2.2.4.19 */ - mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, mod, "constants", mrb_mod_s_constants, MRB_ARGS_ANY()); /* 15.2.2.3.1 */ - mrb_define_class_method(mrb, mod, "nesting", mrb_mod_s_nesting, MRB_ARGS_REQ(0)); /* 15.2.2.3.2 */ - - mrb_undef_method(mrb, cls, "append_features"); - mrb_undef_method(mrb, cls, "extend_object"); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/codedump.c b/web/server/h2o/libh2o/deps/mruby/src/codedump.c deleted file mode 100644 index e3a33419c..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/codedump.c +++ /dev/null @@ -1,474 +0,0 @@ -#include <mruby.h> -#include <mruby/irep.h> -#include <mruby/debug.h> -#include <mruby/opcode.h> -#include <mruby/string.h> -#include <mruby/proc.h> - -#ifndef MRB_DISABLE_STDIO -static int -print_r(mrb_state *mrb, mrb_irep *irep, size_t n, int pre) -{ - size_t i; - - if (n == 0) return 0; - - for (i=0; i+1<irep->nlocals; i++) { - if (irep->lv[i].r == n) { - mrb_sym sym = irep->lv[i].name; - if (pre) printf(" "); - printf("R%d:%s", (int)n, mrb_sym2name(mrb, sym)); - return 1; - } - } - return 0; -} - -#define RA 1 -#define RB 2 -#define RAB 3 - -static void -print_lv(mrb_state *mrb, mrb_irep *irep, mrb_code c, int r) -{ - int pre = 0; - - if (!irep->lv - || ((!(r & RA) || GETARG_A(c) >= irep->nlocals) - && (!(r & RB) || GETARG_B(c) >= irep->nlocals))) { - printf("\n"); - return; - } - printf("\t; "); - if (r & RA) { - pre = print_r(mrb, irep, GETARG_A(c), 0); - } - if (r & RB) { - print_r(mrb, irep, GETARG_B(c), pre); - } - printf("\n"); -} -#endif - -static void -codedump(mrb_state *mrb, mrb_irep *irep) -{ -#ifndef MRB_DISABLE_STDIO - int i; - int ai; - mrb_code c; - const char *file = NULL, *next_file; - int32_t line; - - if (!irep) return; - printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", (void*)irep, - irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen); - - for (i = 0; i < (int)irep->ilen; i++) { - ai = mrb_gc_arena_save(mrb); - - next_file = mrb_debug_get_filename(irep, i); - if (next_file && file != next_file) { - printf("file: %s\n", next_file); - file = next_file; - } - line = mrb_debug_get_line(irep, i); - if (line < 0) { - printf(" "); - } - else { - printf("%5d ", line); - } - - printf("%03d ", i); - c = irep->iseq[i]; - switch (GET_OPCODE(c)) { - case OP_NOP: - printf("OP_NOP\n"); - break; - case OP_MOVE: - printf("OP_MOVE\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_LOADL: - { - mrb_value v = irep->pool[GETARG_Bx(c)]; - mrb_value s = mrb_inspect(mrb, v); - printf("OP_LOADL\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s)); - } - print_lv(mrb, irep, c, RA); - break; - case OP_LOADI: - printf("OP_LOADI\tR%d\t%d\t", GETARG_A(c), GETARG_sBx(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_LOADSYM: - printf("OP_LOADSYM\tR%d\t:%s", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); - print_lv(mrb, irep, c, RA); - break; - case OP_LOADNIL: - printf("OP_LOADNIL\tR%d\t\t", GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_LOADSELF: - printf("OP_LOADSELF\tR%d\t\t", GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_LOADT: - printf("OP_LOADT\tR%d\t\t", GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_LOADF: - printf("OP_LOADF\tR%d\t\t", GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_GETGLOBAL: - 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; - case OP_SETGLOBAL: - printf("OP_SETGLOBAL\t:%s\tR%d\t", - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), - GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_GETCONST: - printf("OP_GETCONST\tR%d\t:%s", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); - print_lv(mrb, irep, c, RA); - break; - case OP_SETCONST: - printf("OP_SETCONST\t:%s\tR%d\t", - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), - GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_GETMCNST: - printf("OP_GETMCNST\tR%d\tR%d::%s", GETARG_A(c), GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); - print_lv(mrb, irep, c, RAB); - break; - case OP_SETMCNST: - printf("OP_SETMCNST\tR%d::%s\tR%d", GETARG_A(c)+1, - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), - GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_GETIV: - printf("OP_GETIV\tR%d\t%s", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); - print_lv(mrb, irep, c, RA); - break; - case OP_SETIV: - printf("OP_SETIV\t%s\tR%d", - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), - GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_GETUPVAR: - printf("OP_GETUPVAR\tR%d\t%d\t%d", - GETARG_A(c), GETARG_B(c), GETARG_C(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_SETUPVAR: - printf("OP_SETUPVAR\tR%d\t%d\t%d", - GETARG_A(c), GETARG_B(c), GETARG_C(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_GETCV: - printf("OP_GETCV\tR%d\t%s", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); - print_lv(mrb, irep, c, RA); - break; - case OP_SETCV: - printf("OP_SETCV\t%s\tR%d", - mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), - GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_JMP: - printf("OP_JMP\t%03d\n", i+GETARG_sBx(c)); - break; - case OP_JMPIF: - printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c)); - break; - case OP_JMPNOT: - printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c)); - break; - case OP_SEND: - printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_SENDB: - printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_TAILCALL: - printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_SUPER: - printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c), - GETARG_C(c)); - break; - case OP_ARGARY: - printf("OP_ARGARY\tR%d\t%d:%d:%d:%d", GETARG_A(c), - (GETARG_Bx(c)>>10)&0x3f, - (GETARG_Bx(c)>>9)&0x1, - (GETARG_Bx(c)>>4)&0x1f, - (GETARG_Bx(c)>>0)&0xf); - print_lv(mrb, irep, c, RA); - break; - - case OP_ENTER: - printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n", - (GETARG_Ax(c)>>18)&0x1f, - (GETARG_Ax(c)>>13)&0x1f, - (GETARG_Ax(c)>>12)&0x1, - (GETARG_Ax(c)>>7)&0x1f, - (GETARG_Ax(c)>>2)&0x1f, - (GETARG_Ax(c)>>1)&0x1, - GETARG_Ax(c) & 0x1); - break; - case OP_RETURN: - printf("OP_RETURN\tR%d", GETARG_A(c)); - switch (GETARG_B(c)) { - case OP_R_NORMAL: - printf("\tnormal\t"); break; - case OP_R_RETURN: - printf("\treturn\t"); break; - case OP_R_BREAK: - printf("\tbreak\t"); break; - default: - printf("\tbroken\t"); break; - } - print_lv(mrb, irep, c, RA); - break; - case OP_BLKPUSH: - printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d", GETARG_A(c), - (GETARG_Bx(c)>>10)&0x3f, - (GETARG_Bx(c)>>9)&0x1, - (GETARG_Bx(c)>>4)&0x1f, - (GETARG_Bx(c)>>0)&0xf); - print_lv(mrb, irep, c, RA); - break; - - case OP_LAMBDA: - printf("OP_LAMBDA\tR%d\tI(%+d)\t", GETARG_A(c), GETARG_b(c)+1); - switch (GETARG_c(c)) { - case OP_L_METHOD: - printf("method"); break; - case OP_L_BLOCK: - printf("block"); break; - case OP_L_LAMBDA: - printf("lambda"); break; - } - print_lv(mrb, irep, c, RA); - break; - case OP_RANGE: - printf("OP_RANGE\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_METHOD: - printf("OP_METHOD\tR%d\t:%s", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); - print_lv(mrb, irep, c, RA); - break; - - case OP_ADD: - printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_ADDI: - printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_SUB: - printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_SUBI: - printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_MUL: - printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_DIV: - printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_LT: - printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_LE: - printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_GT: - printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_GE: - printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - case OP_EQ: - printf("OP_EQ\t\tR%d\t:%s\t%d\n", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), - GETARG_C(c)); - break; - - case OP_STOP: - printf("OP_STOP\n"); - break; - - case OP_ARRAY: - printf("OP_ARRAY\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_ARYCAT: - printf("OP_ARYCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_ARYPUSH: - printf("OP_ARYPUSH\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_AREF: - printf("OP_AREF\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_APOST: - printf("OP_APOST\tR%d\t%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_STRING: - { - mrb_value v = irep->pool[GETARG_Bx(c)]; - mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); - printf("OP_STRING\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s)); - } - print_lv(mrb, irep, c, RA); - break; - case OP_STRCAT: - printf("OP_STRCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_HASH: - printf("OP_HASH\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); - print_lv(mrb, irep, c, RAB); - break; - - case OP_OCLASS: - printf("OP_OCLASS\tR%d\t\t", GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_CLASS: - printf("OP_CLASS\tR%d\t:%s", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); - print_lv(mrb, irep, c, RA); - break; - case OP_MODULE: - printf("OP_MODULE\tR%d\t:%s", GETARG_A(c), - mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); - print_lv(mrb, irep, c, RA); - break; - case OP_EXEC: - printf("OP_EXEC\tR%d\tI(%+d)", GETARG_A(c), GETARG_Bx(c)+1); - print_lv(mrb, irep, c, RA); - break; - case OP_SCLASS: - printf("OP_SCLASS\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); - print_lv(mrb, irep, c, RAB); - break; - case OP_TCLASS: - printf("OP_TCLASS\tR%d\t\t", GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_ERR: - { - mrb_value v = irep->pool[GETARG_Bx(c)]; - mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); - printf("OP_ERR\t%s\n", RSTRING_PTR(s)); - } - break; - case OP_EPUSH: - printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)+1); - break; - case OP_ONERR: - printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c)); - break; - case OP_RESCUE: - { - int a = GETARG_A(c); - int b = GETARG_B(c); - int cnt = GETARG_C(c); - - if (b == 0) { - printf("OP_RESCUE\tR%d\t\t%s", a, cnt ? "cont" : ""); - print_lv(mrb, irep, c, RA); - break; - } - else { - printf("OP_RESCUE\tR%d\tR%d\t%s", a, b, cnt ? "cont" : ""); - print_lv(mrb, irep, c, RAB); - break; - } - } - break; - case OP_RAISE: - printf("OP_RAISE\tR%d\t\t", GETARG_A(c)); - print_lv(mrb, irep, c, RA); - break; - case OP_POPERR: - printf("OP_POPERR\t%d\t\t\n", GETARG_A(c)); - break; - case OP_EPOP: - printf("OP_EPOP\t%d\n", GETARG_A(c)); - break; - - default: - printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c), - GETARG_A(c), GETARG_B(c), GETARG_C(c)); - break; - } - mrb_gc_arena_restore(mrb, ai); - } - printf("\n"); -#endif -} - -static void -codedump_recur(mrb_state *mrb, mrb_irep *irep) -{ - int i; - - codedump(mrb, irep); - for (i=0; i<irep->rlen; i++) { - codedump_recur(mrb, irep->reps[i]); - } -} - -void -mrb_codedump_all(mrb_state *mrb, struct RProc *proc) -{ - codedump_recur(mrb, proc->body.irep); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/compar.c b/web/server/h2o/libh2o/deps/mruby/src/compar.c deleted file mode 100644 index 0032fc859..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/compar.c +++ /dev/null @@ -1,13 +0,0 @@ -/* -** compar.c - Comparable module -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> - -void -mrb_init_comparable(mrb_state *mrb) -{ - mrb_define_module(mrb, "Comparable"); /* 15.3.3 */ -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/crc.c b/web/server/h2o/libh2o/deps/mruby/src/crc.c deleted file mode 100644 index 290b2ca0e..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/crc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* -** crc.c - calculate CRC -** -** See Copyright Notice in mruby.h -*/ - -#include <limits.h> -#include <stdint.h> -#include <stddef.h> - -/* Calculate CRC (CRC-16-CCITT) -** -** 0000_0000_0000_0000_0000_0000_0000_0000 -** ^|------- CRC -------|- work --| -** carry -*/ -#define CRC_16_CCITT 0x11021ul /* x^16+x^12+x^5+1 */ -#define CRC_XOR_PATTERN (CRC_16_CCITT << 8) -#define CRC_CARRY_BIT (0x01000000) - -uint16_t -calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc) -{ - size_t ibyte; - uint32_t ibit; - uint32_t crcwk = crc << 8; - - for (ibyte = 0; ibyte < nbytes; ibyte++) { - crcwk |= *src++; - for (ibit = 0; ibit < CHAR_BIT; ibit++) { - crcwk <<= 1; - if (crcwk & CRC_CARRY_BIT) { - crcwk ^= CRC_XOR_PATTERN; - } - } - } - return (uint16_t)(crcwk >> 8); -} - diff --git a/web/server/h2o/libh2o/deps/mruby/src/debug.c b/web/server/h2o/libh2o/deps/mruby/src/debug.c deleted file mode 100644 index e55f11d4f..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/debug.c +++ /dev/null @@ -1,217 +0,0 @@ -#include <string.h> -#include <mruby.h> -#include <mruby/irep.h> -#include <mruby/debug.h> - -static mrb_irep_debug_info_file* -get_file(mrb_irep_debug_info *info, uint32_t pc) -{ - mrb_irep_debug_info_file **ret; - int32_t count; - - if (pc >= info->pc_count) { return NULL; } - /* get upper bound */ - ret = info->files; - count = info->flen; - while (count > 0) { - int32_t step = count / 2; - mrb_irep_debug_info_file **it = ret + step; - if (!(pc < (*it)->start_pos)) { - ret = it + 1; - count -= step + 1; - } - else { count = step; } - } - - --ret; - - /* check returning file exists inside debug info */ - mrb_assert(info->files <= ret && ret < (info->files + info->flen)); - /* check pc is within the range of returning file */ - mrb_assert((*ret)->start_pos <= pc && - pc < (((ret + 1 - info->files) < info->flen) - ? (*(ret+1))->start_pos : info->pc_count)); - - return *ret; -} - -static mrb_debug_line_type -select_line_type(const uint16_t *lines, size_t lines_len) -{ - size_t line_count = 0; - int prev_line = -1; - size_t i; - for (i = 0; i < lines_len; ++i) { - if (lines[i] != prev_line) { - ++line_count; - } - } - return (sizeof(uint16_t) * lines_len) <= (sizeof(mrb_irep_debug_info_line) * line_count) - ? mrb_debug_line_ary : mrb_debug_line_flat_map; -} - -MRB_API char const* -mrb_debug_get_filename(mrb_irep *irep, ptrdiff_t pc) -{ - if (irep && pc >= 0 && pc < irep->ilen) { - mrb_irep_debug_info_file* f = NULL; - if (!irep->debug_info) { return irep->filename; } - else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { - return f->filename; - } - } - return NULL; -} - -MRB_API int32_t -mrb_debug_get_line(mrb_irep *irep, ptrdiff_t pc) -{ - if (irep && pc >= 0 && pc < irep->ilen) { - mrb_irep_debug_info_file* f = NULL; - if (!irep->debug_info) { - return irep->lines? irep->lines[pc] : -1; - } - else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { - switch (f->line_type) { - case mrb_debug_line_ary: - mrb_assert(f->start_pos <= pc && pc < (f->start_pos + f->line_entry_count)); - return f->lines.ary[pc - f->start_pos]; - - case mrb_debug_line_flat_map: { - /* get upper bound */ - mrb_irep_debug_info_line *ret = f->lines.flat_map; - uint32_t count = f->line_entry_count; - while (count > 0) { - int32_t step = count / 2; - mrb_irep_debug_info_line *it = ret + step; - if (!(pc < it->start_pos)) { - ret = it + 1; - count -= step + 1; - } - else { count = step; } - } - - --ret; - - /* check line entry pointer range */ - mrb_assert(f->lines.flat_map <= ret && ret < (f->lines.flat_map + f->line_entry_count)); - /* check pc range */ - mrb_assert(ret->start_pos <= pc && - pc < (((uint32_t)(ret + 1 - f->lines.flat_map) < f->line_entry_count) - ? (ret+1)->start_pos : irep->debug_info->pc_count)); - - return ret->line; - } - } - } - } - return -1; -} - -MRB_API mrb_irep_debug_info* -mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) -{ - static const mrb_irep_debug_info initial = { 0, 0, NULL }; - mrb_irep_debug_info *ret; - - mrb_assert(!irep->debug_info); - ret = (mrb_irep_debug_info *)mrb_malloc(mrb, sizeof(*ret)); - *ret = initial; - irep->debug_info = ret; - return ret; -} - -MRB_API mrb_irep_debug_info_file* -mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep, - uint32_t start_pos, uint32_t end_pos) -{ - mrb_irep_debug_info *info; - mrb_irep_debug_info_file *ret; - uint32_t file_pc_count; - size_t fn_len; - mrb_int len; - uint32_t i; - - if (!irep->debug_info) { return NULL; } - - mrb_assert(irep->filename); - mrb_assert(irep->lines); - - info = irep->debug_info; - - if (info->flen > 0 && strcmp(irep->filename, info->files[info->flen - 1]->filename) == 0) { - return NULL; - } - - ret = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*ret)); - info->files = - (mrb_irep_debug_info_file**)( - info->files - ? mrb_realloc(mrb, info->files, sizeof(mrb_irep_debug_info_file*) * (info->flen + 1)) - : mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file*))); - info->files[info->flen++] = ret; - - file_pc_count = end_pos - start_pos; - - ret->start_pos = start_pos; - info->pc_count = end_pos; - - fn_len = strlen(irep->filename); - ret->filename_sym = mrb_intern(mrb, irep->filename, fn_len); - len = 0; - ret->filename = mrb_sym2name_len(mrb, ret->filename_sym, &len); - - ret->line_type = select_line_type(irep->lines + start_pos, end_pos - start_pos); - ret->lines.ptr = NULL; - - switch (ret->line_type) { - case mrb_debug_line_ary: - ret->line_entry_count = file_pc_count; - ret->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count); - for (i = 0; i < file_pc_count; ++i) { - ret->lines.ary[i] = irep->lines[start_pos + i]; - } - break; - - case mrb_debug_line_flat_map: { - uint16_t prev_line = 0; - mrb_irep_debug_info_line m; - ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1); - ret->line_entry_count = 0; - for (i = 0; i < file_pc_count; ++i) { - if (irep->lines[start_pos + i] == prev_line) { continue; } - - ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc( - mrb, ret->lines.flat_map, - sizeof(mrb_irep_debug_info_line) * (ret->line_entry_count + 1)); - m.start_pos = start_pos + i; - m.line = irep->lines[start_pos + i]; - ret->lines.flat_map[ret->line_entry_count] = m; - - /* update */ - ++ret->line_entry_count; - prev_line = irep->lines[start_pos + i]; - } - } break; - - default: mrb_assert(0); break; - } - - return ret; -} - -MRB_API void -mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d) -{ - uint32_t i; - - if (!d) { return; } - - for (i = 0; i < d->flen; ++i) { - mrb_assert(d->files[i]); - mrb_free(mrb, d->files[i]->lines.ptr); - mrb_free(mrb, d->files[i]); - } - mrb_free(mrb, d->files); - mrb_free(mrb, d); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/dump.c b/web/server/h2o/libh2o/deps/mruby/src/dump.c deleted file mode 100644 index d479a1a4f..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/dump.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* -** dump.c - mruby binary dumper (mrbc binary format) -** -** See Copyright Notice in mruby.h -*/ - -#include <string.h> -#include <limits.h> -#include <mruby/dump.h> -#include <mruby/string.h> -#include <mruby/irep.h> -#include <mruby/numeric.h> -#include <mruby/debug.h> - -#define FLAG_BYTEORDER_NATIVE 2 -#define FLAG_BYTEORDER_NONATIVE 0 - -#ifdef MRB_USE_FLOAT -#define MRB_FLOAT_FMT "%.8e" -#else -#define MRB_FLOAT_FMT "%.16e" -#endif - -static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); - -#if UINT32_MAX > SIZE_MAX -# error This code cannot be built on your environment. -#endif - -static size_t -write_padding(uint8_t *buf) -{ - const size_t align = MRB_DUMP_ALIGNMENT; - size_t pad_len = -(intptr_t)buf & (align-1); - if (pad_len > 0) { - memset(buf, 0, pad_len); - } - return pad_len; -} - -static size_t -get_irep_header_size(mrb_state *mrb) -{ - size_t size = 0; - - size += sizeof(uint32_t) * 1; - size += sizeof(uint16_t) * 3; - - return size; -} - -static ptrdiff_t -write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) -{ - uint8_t *cur = buf; - - cur += uint32_to_bin((uint32_t)get_irep_record_size_1(mrb, irep), cur); /* record size */ - cur += uint16_to_bin((uint16_t)irep->nlocals, cur); /* number of local variable */ - cur += uint16_to_bin((uint16_t)irep->nregs, cur); /* number of register variable */ - cur += uint16_to_bin((uint16_t)irep->rlen, cur); /* number of child irep */ - - return cur - buf; -} - - -static size_t -get_iseq_block_size(mrb_state *mrb, mrb_irep *irep) -{ - size_t size = 0; - - size += sizeof(uint32_t); /* ilen */ - size += sizeof(uint32_t); /* max padding */ - size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */ - - return size; -} - -static ptrdiff_t -write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) -{ - uint8_t *cur = buf; - int iseq_no; - - cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ - cur += write_padding(cur); - switch (flags & DUMP_ENDIAN_NAT) { - case DUMP_ENDIAN_BIG: - if (bigendian_p()) goto native; - for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { - cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ - } - break; - case DUMP_ENDIAN_LIL: - if (!bigendian_p()) goto native; - for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { - cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */ - } - break; - - native: - case DUMP_ENDIAN_NAT: - memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); - cur += irep->ilen * sizeof(mrb_code); - break; - } - - return cur - buf; -} - - -static size_t -get_pool_block_size(mrb_state *mrb, mrb_irep *irep) -{ - int pool_no; - size_t size = 0; - mrb_value str; - - size += sizeof(uint32_t); /* plen */ - size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */ - - for (pool_no = 0; pool_no < irep->plen; pool_no++) { - int ai = mrb_gc_arena_save(mrb); - - switch (mrb_type(irep->pool[pool_no])) { - case MRB_TT_FIXNUM: - str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); - { - mrb_int len = RSTRING_LEN(str); - mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); - size += (size_t)len; - } - break; - - case MRB_TT_FLOAT: - str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); - { - mrb_int len = RSTRING_LEN(str); - mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); - size += (size_t)len; - } - break; - - case MRB_TT_STRING: - { - mrb_int len = RSTRING_LEN(irep->pool[pool_no]); - mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); - size += (size_t)len; - } - break; - - default: - break; - } - mrb_gc_arena_restore(mrb, ai); - } - - return size; -} - -static ptrdiff_t -write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) -{ - int pool_no; - uint8_t *cur = buf; - uint16_t len; - mrb_value str; - const char *char_ptr; - - cur += uint32_to_bin(irep->plen, cur); /* number of pool */ - - for (pool_no = 0; pool_no < irep->plen; pool_no++) { - int ai = mrb_gc_arena_save(mrb); - - switch (mrb_type(irep->pool[pool_no])) { - case MRB_TT_FIXNUM: - cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */ - str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); - break; - - 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); - break; - - case MRB_TT_STRING: - cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */ - str = irep->pool[pool_no]; - break; - - default: - continue; - } - - char_ptr = RSTRING_PTR(str); - { - mrb_int tlen = RSTRING_LEN(str); - mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX); - len = (uint16_t)tlen; - } - - cur += uint16_to_bin(len, cur); /* data length */ - memcpy(cur, char_ptr, (size_t)len); - cur += len; - - mrb_gc_arena_restore(mrb, ai); - } - - return cur - buf; -} - - -static size_t -get_syms_block_size(mrb_state *mrb, mrb_irep *irep) -{ - size_t size = 0; - int sym_no; - mrb_int len; - - size += sizeof(uint32_t); /* slen */ - for (sym_no = 0; sym_no < irep->slen; sym_no++) { - size += sizeof(uint16_t); /* snl(n) */ - if (irep->syms[sym_no] != 0) { - mrb_sym2name_len(mrb, irep->syms[sym_no], &len); - size += len + 1; /* sn(n) + null char */ - } - } - - return size; -} - -static ptrdiff_t -write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) -{ - int sym_no; - uint8_t *cur = buf; - const char *name; - - cur += uint32_to_bin(irep->slen, cur); /* number of symbol */ - - for (sym_no = 0; sym_no < irep->slen; sym_no++) { - if (irep->syms[sym_no] != 0) { - mrb_int len; - - name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); - - mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX); - cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */ - memcpy(cur, name, len); /* symbol name */ - cur += (uint16_t)len; - *cur++ = '\0'; - } - else { - cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */ - } - } - - return cur - buf; -} - -static size_t -get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep) -{ - size_t size = 0; - - size += get_irep_header_size(mrb); - size += get_iseq_block_size(mrb, irep); - size += get_pool_block_size(mrb, irep); - size += get_syms_block_size(mrb, irep); - return size; -} - -static size_t -get_irep_record_size(mrb_state *mrb, mrb_irep *irep) -{ - size_t size = 0; - int irep_no; - - size = get_irep_record_size_1(mrb, irep); - for (irep_no = 0; irep_no < irep->rlen; irep_no++) { - size += get_irep_record_size(mrb, irep->reps[irep_no]); - } - return size; -} - -static int -write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *irep_record_size, uint8_t flags) -{ - int i; - uint8_t *src = bin; - - if (irep == NULL) { - return MRB_DUMP_INVALID_IREP; - } - - *irep_record_size = get_irep_record_size_1(mrb, irep); - if (*irep_record_size == 0) { - return MRB_DUMP_GENERAL_FAILURE; - } - - bin += write_irep_header(mrb, irep, bin); - bin += write_iseq_block(mrb, irep, bin, flags); - bin += write_pool_block(mrb, irep, bin); - bin += write_syms_block(mrb, irep, bin); - - for (i = 0; i < irep->rlen; i++) { - int result; - size_t rsize; - - result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags); - if (result != MRB_DUMP_OK) { - return result; - } - bin += rsize; - } - *irep_record_size = bin - src; - return MRB_DUMP_OK; -} - -static uint32_t -write_footer(mrb_state *mrb, uint8_t *bin) -{ - struct rite_binary_footer footer; - - memcpy(footer.section_ident, RITE_BINARY_EOF, sizeof(footer.section_ident)); - uint32_to_bin(sizeof(struct rite_binary_footer), footer.section_size); - memcpy(bin, &footer, sizeof(struct rite_binary_footer)); - - return sizeof(struct rite_binary_footer); -} - - -static int -write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin) -{ - struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin; - - memcpy(header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(header->section_ident)); - - mrb_assert_int_fit(size_t, section_size, uint32_t, UINT32_MAX); - uint32_to_bin((uint32_t)section_size, header->section_size); - memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version)); - - return MRB_DUMP_OK; -} - -static int -write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *len_p, uint8_t flags) -{ - int result; - size_t rsize = 0; - uint8_t *cur = bin; - - if (mrb == NULL || bin == NULL) { - return MRB_DUMP_INVALID_ARGUMENT; - } - - cur += sizeof(struct rite_section_irep_header); - - result = write_irep_record(mrb, irep, cur, &rsize, flags); - if (result != MRB_DUMP_OK) { - return result; - } - *len_p = cur - bin + rsize; - write_section_irep_header(mrb, *len_p, bin); - - return MRB_DUMP_OK; -} - -static int -write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin) -{ - struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin; - - memcpy(header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(header->section_ident)); - uint32_to_bin((uint32_t)section_size, header->section_size); - - return MRB_DUMP_OK; -} - -static size_t -get_lineno_record_size(mrb_state *mrb, mrb_irep *irep) -{ - size_t size = 0; - - size += sizeof(uint32_t); /* record size */ - size += sizeof(uint16_t); /* filename size */ - if (irep->filename) { - size += strlen(irep->filename); /* filename */ - } - size += sizeof(uint32_t); /* niseq */ - if (irep->lines) { - size += sizeof(uint16_t) * irep->ilen; /* lineno */ - } - - return size; -} - -static size_t -write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) -{ - uint8_t *cur = bin; - int iseq_no; - size_t filename_len; - ptrdiff_t diff; - - cur += sizeof(uint32_t); /* record size */ - - if (irep->filename) { - filename_len = strlen(irep->filename); - } - else { - filename_len = 0; - } - mrb_assert_int_fit(size_t, filename_len, uint16_t, UINT16_MAX); - cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */ - - if (filename_len) { - memcpy(cur, irep->filename, filename_len); - cur += filename_len; /* filename */ - } - - if (irep->lines) { - mrb_assert_int_fit(size_t, irep->ilen, uint32_t, UINT32_MAX); - cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */ - for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { - cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */ - } - } - else { - cur += uint32_to_bin(0, cur); /* niseq */ - } - - diff = cur - bin; - mrb_assert_int_fit(ptrdiff_t, diff, uint32_t, UINT32_MAX); - - uint32_to_bin((uint32_t)diff, bin); /* record size */ - - mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); - return (size_t)diff; -} - -static size_t -write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) -{ - size_t rlen, size = 0; - int i; - - rlen = write_lineno_record_1(mrb, irep, bin); - bin += rlen; - size += rlen; - for (i=0; i<irep->rlen; i++) { - rlen = write_lineno_record(mrb, irep, bin); - bin += rlen; - size += rlen; - } - return size; -} - -static int -write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) -{ - size_t section_size = 0; - size_t rlen = 0; /* size of irep record */ - uint8_t *cur = bin; - - if (mrb == NULL || bin == NULL) { - return MRB_DUMP_INVALID_ARGUMENT; - } - - cur += sizeof(struct rite_section_lineno_header); - section_size += sizeof(struct rite_section_lineno_header); - - rlen = write_lineno_record(mrb, irep, cur); - section_size += rlen; - - write_section_lineno_header(mrb, section_size, bin); - - return MRB_DUMP_OK; -} - -static size_t -get_debug_record_size(mrb_state *mrb, mrb_irep *irep) -{ - size_t ret = 0; - uint16_t f_idx; - int i; - - ret += sizeof(uint32_t); /* record size */ - ret += sizeof(uint16_t); /* file count */ - - for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { - mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx]; - - ret += sizeof(uint32_t); /* position */ - ret += sizeof(uint16_t); /* filename index */ - - /* lines */ - ret += sizeof(uint32_t); /* entry count */ - ret += sizeof(uint8_t); /* line type */ - switch (file->line_type) { - case mrb_debug_line_ary: - ret += sizeof(uint16_t) * (size_t)(file->line_entry_count); - break; - - case mrb_debug_line_flat_map: - ret += (sizeof(uint32_t) + sizeof(uint16_t)) * (size_t)(file->line_entry_count); - break; - - default: mrb_assert(0); break; - } - } - for (i=0; i<irep->rlen; i++) { - ret += get_debug_record_size(mrb, irep->reps[i]); - } - - return ret; -} - -static int -find_filename_index(const mrb_sym *ary, int ary_len, mrb_sym s) -{ - int i; - - for (i = 0; i < ary_len; ++i) { - if (ary[i] == s) { return i; } - } - return -1; -} - -static size_t -get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp) -{ - mrb_sym *filenames = *fp; - size_t size = 0; - mrb_irep_debug_info *di = irep->debug_info; - int i; - - mrb_assert(lp); - for (i = 0; i < di->flen; ++i) { - mrb_irep_debug_info_file *file; - mrb_int filename_len; - - file = di->files[i]; - if (find_filename_index(filenames, *lp, file->filename_sym) == -1) { - /* register filename */ - *lp += 1; - *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); - filenames[*lp - 1] = file->filename_sym; - - /* filename */ - mrb_sym2name_len(mrb, file->filename_sym, &filename_len); - size += sizeof(uint16_t) + (size_t)filename_len; - } - } - for (i=0; i<irep->rlen; i++) { - size += get_filename_table_size(mrb, irep->reps[i], fp, lp); - } - return size; -} - -static size_t -write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) -{ - uint8_t *cur; - uint16_t f_idx; - ptrdiff_t ret; - - cur = bin + sizeof(uint32_t); /* skip record size */ - cur += uint16_to_bin(irep->debug_info->flen, cur); /* file count */ - - for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { - int filename_idx; - const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; - - /* position */ - cur += uint32_to_bin(file->start_pos, cur); - - /* filename index */ - filename_idx = find_filename_index(filenames, filenames_len, - file->filename_sym); - mrb_assert_int_fit(int, filename_idx, uint16_t, UINT16_MAX); - cur += uint16_to_bin((uint16_t)filename_idx, cur); - - /* lines */ - cur += uint32_to_bin(file->line_entry_count, cur); - cur += uint8_to_bin(file->line_type, cur); - switch (file->line_type) { - case mrb_debug_line_ary: { - uint32_t l; - for (l = 0; l < file->line_entry_count; ++l) { - cur += uint16_to_bin(file->lines.ary[l], cur); - } - } break; - - case mrb_debug_line_flat_map: { - uint32_t line; - for (line = 0; line < file->line_entry_count; ++line) { - cur += uint32_to_bin(file->lines.flat_map[line].start_pos, cur); - cur += uint16_to_bin(file->lines.flat_map[line].line, cur); - } - } break; - - default: mrb_assert(0); break; - } - } - - ret = cur - bin; - mrb_assert_int_fit(ptrdiff_t, ret, uint32_t, UINT32_MAX); - uint32_to_bin((uint32_t)ret, bin); - - mrb_assert_int_fit(ptrdiff_t, ret, size_t, SIZE_MAX); - return (size_t)ret; -} - -static size_t -write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) -{ - size_t size, len; - int irep_no; - - size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len); - bin += len; - for (irep_no = 0; irep_no < irep->rlen; irep_no++) { - len = write_debug_record(mrb, irep->reps[irep_no], bin, filenames, filenames_len); - bin += len; - size += len; - } - - mrb_assert(size == get_debug_record_size(mrb, irep)); - return size; -} - -static int -write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur, mrb_sym const *filenames, uint16_t filenames_len) -{ - size_t section_size = 0; - const uint8_t *bin = cur; - struct rite_section_debug_header *header; - size_t dlen; - uint16_t i; - char const *sym; mrb_int sym_len; - - if (mrb == NULL || cur == NULL) { - return MRB_DUMP_INVALID_ARGUMENT; - } - - header = (struct rite_section_debug_header *)bin; - cur += sizeof(struct rite_section_debug_header); - section_size += sizeof(struct rite_section_debug_header); - - /* filename table */ - cur += uint16_to_bin(filenames_len, cur); - section_size += sizeof(uint16_t); - for (i = 0; i < filenames_len; ++i) { - sym = mrb_sym2name_len(mrb, filenames[i], &sym_len); - mrb_assert(sym); - cur += uint16_to_bin(sym_len, cur); - memcpy(cur, sym, sym_len); - cur += sym_len; - section_size += sizeof(uint16_t) + sym_len; - } - - /* debug records */ - dlen = write_debug_record(mrb, irep, cur, filenames, filenames_len); - section_size += dlen; - - memcpy(header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(header->section_ident)); - mrb_assert(section_size <= INT32_MAX); - uint32_to_bin((uint32_t)section_size, header->section_size); - - return MRB_DUMP_OK; -} - -static void -create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len) -{ - int 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; - int 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; - int 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_ident, RITE_SECTION_LV_IDENT, sizeof(header->section_ident)); - - diff = cur - start; - mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); - uint32_to_bin((uint32_t)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, uint8_t flags) -{ - struct rite_binary_header *header = (struct rite_binary_header *)bin; - 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_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)); - mrb_assert(binary_size <= UINT32_MAX); - uint32_to_bin((uint32_t)binary_size, header->binary_size); - - offset = (uint32_t)((&(header->binary_crc[0]) - bin) + sizeof(uint16_t)); - crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0); - uint16_to_bin(crc, header->binary_crc); - - return MRB_DUMP_OK; -} - -static mrb_bool -is_debug_info_defined(mrb_irep *irep) -{ - int i; - - if (!irep->debug_info) return FALSE; - for (i=0; i<irep->rlen; i++) { - if (!is_debug_info_defined(irep->reps[i])) return FALSE; - } - return TRUE; -} - -static mrb_bool -is_lv_defined(mrb_irep *irep) -{ - int i; - - if (irep->lv) { return TRUE; } - - for (i = 0; i < irep->rlen; ++i) { - if (is_lv_defined(irep->reps[i])) { return TRUE; } - } - - 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) -{ - int result = MRB_DUMP_GENERAL_FAILURE; - size_t malloc_size; - size_t section_irep_size; - 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), lv_defined = is_lv_defined(irep); - mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0; - mrb_sym *filenames = NULL; uint16_t filenames_len = 0; - - if (mrb == NULL) { - *bin = NULL; - return MRB_DUMP_GENERAL_FAILURE; - } - - section_irep_size = sizeof(struct rite_section_irep_header); - section_irep_size += get_irep_record_size(mrb, irep); - - /* DEBUG section size */ - if (flags & DUMP_DEBUG_INFO) { - if (debug_info_defined) { - section_lineno_size += sizeof(struct rite_section_debug_header); - /* filename table */ - filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) + 1); - - /* filename table size */ - section_lineno_size += sizeof(uint16_t); - section_lineno_size += get_filename_table_size(mrb, irep, &filenames, &filenames_len); - - section_lineno_size += get_debug_record_size(mrb, irep); - } - else { - section_lineno_size += sizeof(struct rite_section_lineno_header); - section_lineno_size += get_lineno_record_size(mrb, irep); - } - } - - 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); - } - - malloc_size = sizeof(struct rite_binary_header) + - section_irep_size + section_lineno_size + section_lv_size + - sizeof(struct rite_binary_footer); - cur = *bin = (uint8_t*)mrb_malloc(mrb, malloc_size); - cur += sizeof(struct rite_binary_header); - - result = write_section_irep(mrb, irep, cur, §ion_irep_size, flags); - if (result != MRB_DUMP_OK) { - goto error_exit; - } - cur += section_irep_size; - *bin_size = sizeof(struct rite_binary_header) + - section_irep_size + section_lineno_size + section_lv_size + - sizeof(struct rite_binary_footer); - - /* write DEBUG section */ - if (flags & DUMP_DEBUG_INFO) { - if (debug_info_defined) { - result = write_section_debug(mrb, irep, cur, filenames, filenames_len); - } - else { - result = write_section_lineno(mrb, irep, cur); - } - if (result != MRB_DUMP_OK) { - goto error_exit; - } - 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, flags); - -error_exit: - if (result != MRB_DUMP_OK) { - mrb_free(mrb, *bin); - *bin = NULL; - } - mrb_free(mrb, lv_syms); - mrb_free(mrb, filenames); - return result; -} - -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); -} - -#ifndef MRB_DISABLE_STDIO - -int -mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE* fp) -{ - uint8_t *bin = NULL; - size_t bin_size = 0; - int result; - - if (fp == NULL) { - return MRB_DUMP_INVALID_ARGUMENT; - } - - result = dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), &bin, &bin_size); - if (result == MRB_DUMP_OK) { - if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { - result = MRB_DUMP_WRITE_FAULT; - } - } - - mrb_free(mrb, bin); - 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) -{ - uint8_t *bin = NULL; - size_t bin_size = 0, bin_idx = 0; - int result; - - 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; - } - if (fprintf(fp, - "extern const uint8_t %s[];\n" - "const uint8_t\n" - "#if defined __GNUC__\n" - "__attribute__((aligned(%u)))\n" - "#elif defined _MSC_VER\n" - "__declspec(align(%u))\n" - "#endif\n" - "%s[] = {", - initname, - (uint16_t)MRB_DUMP_ALIGNMENT, (uint16_t)MRB_DUMP_ALIGNMENT, initname) < 0) { - mrb_free(mrb, bin); - return MRB_DUMP_WRITE_FAULT; - } - while (bin_idx < bin_size) { - if (bin_idx % 16 == 0) { - if (fputs("\n", fp) == EOF) { - mrb_free(mrb, bin); - return MRB_DUMP_WRITE_FAULT; - } - } - if (fprintf(fp, "0x%02x,", bin[bin_idx++]) < 0) { - mrb_free(mrb, bin); - return MRB_DUMP_WRITE_FAULT; - } - } - if (fputs("\n};\n", fp) == EOF) { - mrb_free(mrb, bin); - return MRB_DUMP_WRITE_FAULT; - } - } - - mrb_free(mrb, bin); - return result; -} - -#endif /* MRB_DISABLE_STDIO */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/enum.c b/web/server/h2o/libh2o/deps/mruby/src/enum.c deleted file mode 100644 index adb815bf1..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/enum.c +++ /dev/null @@ -1,14 +0,0 @@ -/* -** enum.c - Enumerable module -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> - -void -mrb_init_enumerable(mrb_state *mrb) -{ - mrb_define_module(mrb, "Enumerable"); /* 15.3.2 */ -} - diff --git a/web/server/h2o/libh2o/deps/mruby/src/error.c b/web/server/h2o/libh2o/deps/mruby/src/error.c deleted file mode 100644 index 2c4fd1a40..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/error.c +++ /dev/null @@ -1,503 +0,0 @@ -/* -** error.c - Exception class -** -** See Copyright Notice in mruby.h -*/ - -#include <errno.h> -#include <stdarg.h> -#include <stdlib.h> -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/irep.h> -#include <mruby/proc.h> -#include <mruby/string.h> -#include <mruby/variable.h> -#include <mruby/debug.h> -#include <mruby/error.h> -#include <mruby/class.h> -#include <mruby/throw.h> - -MRB_API mrb_value -mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len) -{ - mrb_value arg = mrb_str_new(mrb, ptr, len); - return mrb_obj_new(mrb, c, 1, &arg); -} - -MRB_API mrb_value -mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) -{ - str = mrb_str_to_str(mrb, str); - return mrb_obj_new(mrb, c, 1, &str); -} - -/* - * call-seq: - * Exception.new(msg = nil) -> exception - * - * Construct a new Exception object, optionally passing in - * a message. - */ - -static mrb_value -exc_initialize(mrb_state *mrb, mrb_value exc) -{ - mrb_value mesg; - mrb_int argc; - mrb_value *argv; - - if (mrb_get_args(mrb, "|o*!", &mesg, &argv, &argc) >= 1) { - mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg); - } - return exc; -} - -/* - * Document-method: exception - * - * call-seq: - * exc.exception(string) -> an_exception or exc - * - * With no argument, or if the argument is the same as the receiver, - * return the receiver. Otherwise, create a new - * exception object of the same class as the receiver, but with a - * message equal to <code>string</code>. - * - */ - -static mrb_value -exc_exception(mrb_state *mrb, mrb_value self) -{ - mrb_value exc; - mrb_value a; - int argc; - - argc = mrb_get_args(mrb, "|o", &a); - if (argc == 0) return self; - if (mrb_obj_equal(mrb, self, a)) return self; - exc = mrb_obj_clone(mrb, self); - mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), a); - - return exc; -} - -/* - * call-seq: - * exception.to_s -> string - * - * Returns exception's message (or the name of the exception if - * no message is set). - */ - -static mrb_value -exc_to_s(mrb_state *mrb, mrb_value exc) -{ - mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); - struct RObject *p; - - if (!mrb_string_p(mesg)) { - return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc)); - } - p = mrb_obj_ptr(mesg); - if (!p->c) { - p->c = mrb->string_class; - } - return mesg; -} - -/* - * call-seq: - * exception.message -> string - * - * Returns the result of invoking <code>exception.to_s</code>. - * Normally this returns the exception's message or name. - */ - -static mrb_value -exc_message(mrb_state *mrb, mrb_value exc) -{ - return mrb_funcall(mrb, exc, "to_s", 0); -} - -/* - * call-seq: - * exception.inspect -> string - * - * Returns this exception's file name, line number, - * message and class name. - * If file name or line number is not set, - * returns message and class name. - */ - -static mrb_value -exc_inspect(mrb_state *mrb, mrb_value exc) -{ - mrb_value str, mesg, file, line; - mrb_bool append_mesg; - const char *cname; - - mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); - file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); - line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line")); - - append_mesg = !mrb_nil_p(mesg); - if (append_mesg) { - mesg = mrb_obj_as_string(mrb, mesg); - append_mesg = RSTRING_LEN(mesg) > 0; - } - - cname = mrb_obj_classname(mrb, exc); - str = mrb_str_new_cstr(mrb, cname); - if (mrb_string_p(file) && mrb_fixnum_p(line)) { - if (append_mesg) { - str = mrb_format(mrb, "%S:%S: %S (%S)", file, line, mesg, str); - } - else { - str = mrb_format(mrb, "%S:%S: %S", file, line, str); - } - } - else if (append_mesg) { - str = mrb_format(mrb, "%S: %S", str, mesg); - } - return str; -} - -void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc); - -static void -set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace) -{ - if (!mrb_array_p(backtrace)) { - type_err: - mrb_raise(mrb, E_TYPE_ERROR, "backtrace must be Array of String"); - } - else { - const mrb_value *p = RARRAY_PTR(backtrace); - const mrb_value *pend = p + RARRAY_LEN(backtrace); - - while (p < pend) { - if (!mrb_string_p(*p)) goto type_err; - p++; - } - } - mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace); -} - -static mrb_value -exc_set_backtrace(mrb_state *mrb, mrb_value exc) -{ - mrb_value backtrace; - - mrb_get_args(mrb, "o", &backtrace); - set_backtrace(mrb, exc, backtrace); - return backtrace; -} - -static void -exc_debug_info(mrb_state *mrb, struct RObject *exc) -{ - mrb_callinfo *ci = mrb->c->ci; - mrb_code *pc = ci->pc; - - while (ci >= mrb->c->cibase) { - mrb_code *err = ci->err; - - if (!err && pc) err = pc - 1; - if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { - mrb_irep *irep = ci->proc->body.irep; - - int32_t const line = mrb_debug_get_line(irep, err - irep->iseq); - char const* file = mrb_debug_get_filename(irep, err - irep->iseq); - if (line != -1 && file) { - mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file)); - mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line)); - return; - } - } - pc = ci->pc; - ci--; - } -} - -void -mrb_exc_set(mrb_state *mrb, mrb_value exc) -{ - if (mrb_nil_p(exc)) { - mrb->exc = 0; - } - else { - mrb->exc = mrb_obj_ptr(exc); - if (!mrb->gc.out_of_memory) { - exc_debug_info(mrb, mrb->exc); - mrb_keep_backtrace(mrb, exc); - } - } -} - -MRB_API mrb_noreturn void -mrb_exc_raise(mrb_state *mrb, mrb_value exc) -{ - if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { - mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); - } - mrb_exc_set(mrb, exc); - if (!mrb->jmp) { - mrb_p(mrb, exc); - abort(); - } - MRB_THROW(mrb->jmp); -} - -MRB_API mrb_noreturn void -mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg) -{ - mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mrb_str_new_cstr(mrb, msg))); -} - -MRB_API mrb_value -mrb_vformat(mrb_state *mrb, const char *format, va_list ap) -{ - const char *p = format; - const char *b = p; - ptrdiff_t size; - mrb_value ary = mrb_ary_new_capa(mrb, 4); - int ai = mrb_gc_arena_save(mrb); - - while (*p) { - const char c = *p++; - - if (c == '%') { - if (*p == 'S') { - mrb_value val; - - size = p - b - 1; - mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); - val = va_arg(ap, mrb_value); - mrb_ary_push(mrb, ary, mrb_obj_as_string(mrb, val)); - b = p + 1; - } - } - else if (c == '\\') { - if (*p) { - size = p - b - 1; - mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); - mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1)); - b = ++p; - } - else { - break; - } - } - mrb_gc_arena_restore(mrb, ai); - } - if (b == format) { - return mrb_str_new_cstr(mrb, format); - } - else { - size = p - b; - if (size > 0) { - mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); - mrb_gc_arena_restore(mrb, ai); - } - return mrb_ary_join(mrb, ary, mrb_nil_value()); - } -} - -MRB_API mrb_value -mrb_format(mrb_state *mrb, const char *format, ...) -{ - va_list ap; - mrb_value str; - - va_start(ap, format); - str = mrb_vformat(mrb, format, ap); - va_end(ap); - - return str; -} - -static mrb_noreturn void -raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list ap, int argc, mrb_value *argv) -{ - mrb_value mesg; - - mesg = mrb_vformat(mrb, fmt, ap); - if (argv == NULL) { - argv = &mesg; - } - else { - argv[0] = mesg; - } - mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv)); -} - -MRB_API mrb_noreturn void -mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - raise_va(mrb, c, fmt, args, 0, NULL); - va_end(args); -} - -MRB_API mrb_noreturn void -mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...) -{ - mrb_value argv[2]; - va_list args; - - va_start(args, fmt); - argv[1] = mrb_symbol_value(id); - raise_va(mrb, E_NAME_ERROR, fmt, args, 1, argv); - va_end(args); -} - -MRB_API void -mrb_warn(mrb_state *mrb, const char *fmt, ...) -{ -#ifndef MRB_DISABLE_STDIO - va_list ap; - mrb_value str; - - va_start(ap, fmt); - str = mrb_vformat(mrb, fmt, ap); - fputs("warning: ", stderr); - fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); - va_end(ap); -#endif -} - -MRB_API mrb_noreturn void -mrb_bug(mrb_state *mrb, const char *fmt, ...) -{ -#ifndef MRB_DISABLE_STDIO - va_list ap; - mrb_value str; - - va_start(ap, fmt); - str = mrb_vformat(mrb, fmt, ap); - fputs("bug: ", stderr); - fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); - va_end(ap); -#endif - exit(EXIT_FAILURE); -} - -MRB_API mrb_value -mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv) -{ - mrb_value mesg; - int n; - - mesg = mrb_nil_value(); - switch (argc) { - case 0: - break; - case 1: - if (mrb_nil_p(argv[0])) - break; - if (mrb_string_p(argv[0])) { - mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, argv[0]); - break; - } - n = 0; - goto exception_call; - - case 2: - case 3: - n = 1; -exception_call: - { - mrb_sym exc = mrb_intern_lit(mrb, "exception"); - if (mrb_respond_to(mrb, argv[0], exc)) { - mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1); - } - else { - /* undef */ - mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); - } - } - - break; - default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc)); - break; - } - if (argc > 0) { - if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) - mrb_raise(mrb, mrb->eException_class, "exception object expected"); - if (argc > 2) - set_backtrace(mrb, mesg, argv[2]); - } - - return mesg; -} - -MRB_API void -mrb_sys_fail(mrb_state *mrb, const char *mesg) -{ - struct RClass *sce; - mrb_int no; - - no = (mrb_int)errno; - if (mrb_class_defined(mrb, "SystemCallError")) { - sce = mrb_class_get(mrb, "SystemCallError"); - if (mesg != NULL) { - mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); - } - else { - mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no)); - } - } - else { - mrb_raise(mrb, E_RUNTIME_ERROR, mesg); - } -} - -MRB_API mrb_noreturn void -mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, ...) -{ - mrb_value exc; - mrb_value argv[3]; - va_list ap; - - va_start(ap, fmt); - argv[0] = mrb_vformat(mrb, fmt, ap); - argv[1] = mrb_symbol_value(id); - argv[2] = args; - va_end(ap); - exc = mrb_obj_new(mrb, E_NOMETHOD_ERROR, 3, argv); - mrb_exc_raise(mrb, exc); -} - -void -mrb_init_exception(mrb_state *mrb) -{ - struct RClass *exception, *script_error, *stack_error, *nomem_error; - - mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ - MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); - 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, "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_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); - - 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 */ - script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ - mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ - stack_error = mrb_define_class(mrb, "SystemStackError", exception); - mrb->stack_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, stack_error, "stack level too deep")); - - nomem_error = mrb_define_class(mrb, "NoMemoryError", exception); - mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "Out of memory")); -#ifdef MRB_GC_FIXED_ARENA - mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "arena overflow error")); -#endif -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/error.h b/web/server/h2o/libh2o/deps/mruby/src/error.h deleted file mode 100644 index eb755ec7f..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/error.h +++ /dev/null @@ -1,3 +0,0 @@ -/* this header file is to be removed soon. - added for compatibility purpose (1.0.0) */ -#include <mruby/error.h> diff --git a/web/server/h2o/libh2o/deps/mruby/src/etc.c b/web/server/h2o/libh2o/deps/mruby/src/etc.c deleted file mode 100644 index 9475ae304..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/etc.c +++ /dev/null @@ -1,234 +0,0 @@ -/* -** etc.c - -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/string.h> -#include <mruby/data.h> -#include <mruby/class.h> -#include <mruby/re.h> -#include <mruby/irep.h> - -MRB_API struct RData* -mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb_data_type *type) -{ - struct RData *data; - - data = (struct RData*)mrb_obj_alloc(mrb, MRB_TT_DATA, klass); - data->data = ptr; - data->type = type; - - return data; -} - -MRB_API void -mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) -{ - if (mrb_type(obj) != MRB_TT_DATA) { - mrb_check_type(mrb, obj, MRB_TT_DATA); - } - if (DATA_TYPE(obj) != type) { - const mrb_data_type *t2 = DATA_TYPE(obj); - - if (t2) { - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)", - mrb_str_new_cstr(mrb, t2->struct_name), mrb_str_new_cstr(mrb, type->struct_name)); - } - else { - struct RClass *c = mrb_class(mrb, obj); - - mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %S (expected %S)", - mrb_obj_value(c), mrb_str_new_cstr(mrb, type->struct_name)); - } - } -} - -MRB_API void* -mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) -{ - if (mrb_type(obj) != MRB_TT_DATA) { - return NULL; - } - if (DATA_TYPE(obj) != type) { - return NULL; - } - return DATA_PTR(obj); -} - -MRB_API void* -mrb_data_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) -{ - mrb_data_check_type(mrb, obj, type); - return DATA_PTR(obj); -} - -MRB_API mrb_sym -mrb_obj_to_sym(mrb_state *mrb, mrb_value name) -{ - mrb_sym id; - - switch (mrb_type(name)) { - default: - name = mrb_check_string_type(mrb, name); - if (mrb_nil_p(name)) { - name = mrb_inspect(mrb, name); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name); - } - /* fall through */ - case MRB_TT_STRING: - name = mrb_str_intern(mrb, name); - /* fall through */ - case MRB_TT_SYMBOL: - id = mrb_symbol(name); - } - return id; -} - -MRB_API mrb_int -mrb_float_id(mrb_float f) -{ - const char *p = (const char*)&f; - int len = sizeof(f); - mrb_int id = 0; - - /* normalize -0.0 to 0.0 */ - if (f == 0) f = 0.0; - while (len--) { - id = id*65599 + *p; - p++; - } - id = id + (id>>5); - - return id; -} - -MRB_API mrb_int -mrb_obj_id(mrb_value obj) -{ - mrb_int tt = mrb_type(obj); - -#define MakeID2(p,t) (mrb_int)(((intptr_t)(p))^(t)) -#define MakeID(p) MakeID2(p,tt) - - switch (tt) { - case MRB_TT_FREE: - case MRB_TT_UNDEF: - return MakeID(0); /* not define */ - case MRB_TT_FALSE: - if (mrb_nil_p(obj)) - return MakeID(1); - return MakeID(0); - case MRB_TT_TRUE: - return MakeID(1); - case MRB_TT_SYMBOL: - return MakeID(mrb_symbol(obj)); - case MRB_TT_FIXNUM: - return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT); - case MRB_TT_FLOAT: - return MakeID(mrb_float_id(mrb_float(obj))); - case MRB_TT_STRING: - case MRB_TT_OBJECT: - case MRB_TT_CLASS: - case MRB_TT_MODULE: - case MRB_TT_ICLASS: - case MRB_TT_SCLASS: - case MRB_TT_PROC: - case MRB_TT_ARRAY: - case MRB_TT_HASH: - case MRB_TT_RANGE: - case MRB_TT_EXCEPTION: - case MRB_TT_FILE: - case MRB_TT_DATA: - case MRB_TT_ISTRUCT: - default: - return MakeID(mrb_ptr(obj)); - } -} - -#ifdef MRB_WORD_BOXING -MRB_API mrb_value -mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f) -{ - mrb_value v; - - v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class); - v.value.fp->f = f; - return v; -} - -MRB_API mrb_value -mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f) -{ - struct RFloat *nf = (struct RFloat *)mrb_malloc(mrb, sizeof(struct RFloat)); - nf->tt = MRB_TT_FLOAT; - nf->c = mrb->float_class; - nf->f = f; - return mrb_obj_value(nf); -} - -MRB_API mrb_value -mrb_word_boxing_cptr_value(mrb_state *mrb, void *p) -{ - mrb_value v; - - v.value.p = mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class); - v.value.vp->p = p; - return v; -} -#endif /* MRB_WORD_BOXING */ - -MRB_API mrb_bool -mrb_regexp_p(mrb_state *mrb, mrb_value v) -{ - if (mrb->flags & MRB_STATE_NO_REGEXP) { - return FALSE; - } - if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) { - mrb->flags |= MRB_STATE_REGEXP; - return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS)); - } - else { - mrb->flags |= MRB_STATE_REGEXP; - mrb->flags |= MRB_STATE_NO_REGEXP; - } - return FALSE; -} - -#if defined _MSC_VER && _MSC_VER < 1900 - -#ifndef va_copy -static void -mrb_msvc_va_copy(va_list *dest, va_list src) -{ - *dest = src; -} -#define va_copy(dest, src) mrb_msvc_va_copy(&(dest), src) -#endif - -MRB_API int -mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg) -{ - int cnt; - va_list argcp; - va_copy(argcp, arg); - if (n == 0 || (cnt = _vsnprintf_s(s, n, _TRUNCATE, format, argcp)) < 0) { - cnt = _vscprintf(format, arg); - } - va_end(argcp); - return cnt; -} - -MRB_API int -mrb_msvc_snprintf(char *s, size_t n, const char *format, ...) -{ - va_list arg; - int ret; - va_start(arg, format); - ret = mrb_msvc_vsnprintf(s, n, format, arg); - va_end(arg); - return ret; -} - -#endif /* defined _MSC_VER && _MSC_VER < 1900 */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/ext/.gitkeep b/web/server/h2o/libh2o/deps/mruby/src/ext/.gitkeep deleted file mode 100644 index e69de29bb..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/ext/.gitkeep +++ /dev/null diff --git a/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c b/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c deleted file mode 100644 index 0a8b22b41..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - -Most code in this file originates from musl (src/stdio/vfprintf.c) -which, just like mruby itself, is licensed under the MIT license. - -Copyright (c) 2005-2014 Rich Felker, et al. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include <limits.h> -#include <string.h> -#include <stdint.h> -#include <math.h> -#include <float.h> -#include <ctype.h> - -#include <mruby.h> -#include <mruby/string.h> - -struct fmt_args { - mrb_state *mrb; - mrb_value str; -}; - -#define MAX(a,b) ((a)>(b) ? (a) : (b)) -#define MIN(a,b) ((a)<(b) ? (a) : (b)) - -/* Convenient bit representation for modifier flags, which all fall - * within 31 codepoints of the space character. */ - -#define ALT_FORM (1U<<('#'-' ')) -#define ZERO_PAD (1U<<('0'-' ')) -#define LEFT_ADJ (1U<<('-'-' ')) -#define PAD_POS (1U<<(' '-' ')) -#define MARK_POS (1U<<('+'-' ')) - -static void -out(struct fmt_args *f, const char *s, size_t l) -{ - mrb_str_cat(f->mrb, f->str, s, l); -} - -#define PAD_SIZE 256 -static void -pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl) -{ - char pad[PAD_SIZE]; - if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; - l = w - l; - memset(pad, c, l>PAD_SIZE ? PAD_SIZE : l); - for (; l >= PAD_SIZE; l -= PAD_SIZE) - out(f, pad, PAD_SIZE); - out(f, pad, l); -} - -static const char xdigits[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; - -static char* -fmt_u(uint32_t x, char *s) -{ - for (; x; x /= 10) *--s = '0' + x % 10; - return s; -} - -/* Do not override this check. The floating point printing code below - * depends on the float.h constants being right. If they are wrong, it - * may overflow the stack. */ -#if LDBL_MANT_DIG == 53 -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) -{ - uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion - + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion - uint32_t *a, *d, *r, *z; - uint32_t i; - int e2=0, e, j; - ptrdiff_t l; - char buf[9+LDBL_MANT_DIG/4], *s; - const char *prefix="-0X+0X 0X-0x+0x 0x"; - ptrdiff_t pl; - char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr; - - pl=1; - if (signbit(y)) { - y=-y; - } else if (fl & MARK_POS) { - prefix+=3; - } else if (fl & PAD_POS) { - prefix+=6; - } else prefix++, pl=0; - - 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); - out(f, prefix, pl); - out(f, ss, 3); - pad(f, ' ', 0, 3+pl, fl^LEFT_ADJ); - return 3+(int)pl; - } - - y = frexp((double)y, &e2) * 2; - if (y) e2--; - - if ((t|32)=='a') { - long double round = 8.0; - ptrdiff_t re; - - if (t&32) prefix += 9; - pl += 2; - - if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; - else re=LDBL_MANT_DIG/4-1-p; - - if (re) { - while (re--) round*=16; - if (*prefix=='-') { - y=-y; - y-=round; - y+=round; - y=-y; - } - else { - y+=round; - y-=round; - } - } - - estr=fmt_u(e2<0 ? -e2 : e2, ebuf); - if (estr==ebuf) *--estr='0'; - *--estr = (e2<0 ? '-' : '+'); - *--estr = t+('p'-'a'); - - s=buf; - do { - int x=(int)y; - *s++=xdigits[x]|(t&32); - y=16*(y-x); - if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.'; - } while (y); - - if (p && s-buf-2 < p) - l = (p+2) + (ebuf-estr); - else - l = (s-buf) + (ebuf-estr); - - pad(f, ' ', 0, pl+l, fl); - out(f, prefix, pl); - pad(f, '0', 0, 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; - } - if (p<0) p=6; - - if (y) y *= 268435456.0, e2-=28; - - if (e2<0) a=r=z=big; - else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; - - do { - *z = (uint32_t)y; - y = 1000000000*(y-*z++); - } while (y); - - while (e2>0) { - uint32_t carry=0; - int sh=MIN(29,e2); - for (d=z-1; d>=a; d--) { - uint64_t x = ((uint64_t)*d<<sh)+carry; - *d = x % 1000000000; - carry = (uint32_t)(x / 1000000000); - } - if (carry) *--a = carry; - while (z>a && !z[-1]) z--; - e2-=sh; - } - while (e2<0) { - uint32_t carry=0, *b; - int sh=MIN(9,-e2), need=1+((int)p+LDBL_MANT_DIG/3+8)/9; - for (d=a; d<z; d++) { - uint32_t rm = *d & ((1<<sh)-1); - *d = (*d>>sh) + carry; - carry = (1000000000>>sh) * rm; - } - if (!*a) a++; - if (carry) *z++ = carry; - /* Avoid (slow!) computation past requested precision */ - b = (t|32)=='f' ? r : a; - if (z-b > need) z = b+need; - e2+=sh; - } - - if (a<z) for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); - else e=0; - - /* Perform rounding: j is precision after the radix (possibly neg) */ - j = (int)p - ((t|32)!='f')*e - ((t|32)=='g' && p); - if (j < 9*(z-r-1)) { - uint32_t x; - /* We avoid C's broken division of negative numbers */ - d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP); - j += 9*LDBL_MAX_EXP; - j %= 9; - for (i=10, j++; j<9; i*=10, j++); - x = *d % i; - /* Are there any significant digits past j? */ - if (x || d+1!=z) { - long double round = 2/LDBL_EPSILON; - long double small; - if (*d/i & 1) round += 2; - if (x<i/2) small=0.5; - else if (x==i/2 && d+1==z) small=1.0; - else small=1.5; - if (pl && *prefix=='-') round*=-1, small*=-1; - *d -= x; - /* Decide whether to round by probing round+small */ - if (round+small != round) { - *d = *d + i; - while (*d > 999999999) { - *d--=0; - if (d<a) *--a=0; - (*d)++; - } - for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); - } - } - if (z>d+1) z=d+1; - } - for (; z>a && !z[-1]; z--); - - if ((t|32)=='g') { - if (!p) p++; - if (p>e && e>=-4) { - t--; - p-=e+1; - } - else { - t-=2; - p--; - } - if (!(fl&ALT_FORM)) { - /* Count trailing zeros in last place */ - if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++); - else j=9; - if ((t|32)=='f') - p = MIN(p,MAX(0,9*(z-r-1)-j)); - else - p = MIN(p,MAX(0,9*(z-r-1)+e-j)); - } - } - l = 1 + p + (p || (fl&ALT_FORM)); - if ((t|32)=='f') { - if (e>0) l+=e; - } - else { - estr=fmt_u(e<0 ? -e : e, ebuf); - while(ebuf-estr<2) *--estr='0'; - *--estr = (e<0 ? '-' : '+'); - *--estr = t; - l += ebuf-estr; - } - - pad(f, ' ', 0, pl+l, fl); - out(f, prefix, pl); - pad(f, '0', 0, pl+l, fl^ZERO_PAD); - - if ((t|32)=='f') { - if (a>r) a=r; - for (d=a; d<=r; d++) { - char *ss = fmt_u(*d, buf+9); - if (d!=a) while (ss>buf) *--ss='0'; - else if (ss==buf+9) *--ss='0'; - out(f, ss, buf+9-ss); - } - if (p || (fl&ALT_FORM)) out(f, ".", 1); - for (; d<z && p>0; d++, p-=9) { - char *ss = fmt_u(*d, buf+9); - while (ss>buf) *--ss='0'; - out(f, ss, MIN(9,p)); - } - pad(f, '0', p+9, 9, 0); - } - else { - if (z<=a) z=a+1; - for (d=a; d<z && p>=0; d++) { - char *ss = fmt_u(*d, buf+9); - if (ss==buf+9) *--ss='0'; - if (d!=a) while (ss>buf) *--ss='0'; - else { - out(f, ss++, 1); - if (p>0||(fl&ALT_FORM)) out(f, ".", 1); - } - out(f, ss, MIN(buf+9-ss, p)); - p -= (int)(buf+9-ss); - } - pad(f, '0', p+18, 18, 0); - out(f, estr, ebuf-estr); - } - - pad(f, ' ', 0, pl+l, fl^LEFT_ADJ); - - return (int)pl+(int)l; -} - -static int -fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) -{ - ptrdiff_t p; - - if (*fmt != '%') { - return -1; - } - ++fmt; - - if (*fmt == '.') { - ++fmt; - for (p = 0; ISDIGIT(*fmt); ++fmt) { - p = 10 * p + (*fmt - '0'); - } - } - else { - p = -1; - } - - 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); - default: - return -1; - } -} - -mrb_value -mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) -{ - struct fmt_args f; - - f.mrb = mrb; - f.str = mrb_str_new_capa(mrb, 24); - if (fmt_core(&f, fmt, mrb_float(flo)) < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string"); - } - return f.str; -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/gc.c b/web/server/h2o/libh2o/deps/mruby/src/gc.c deleted file mode 100644 index d602bfb70..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/gc.c +++ /dev/null @@ -1,1824 +0,0 @@ -/* -** gc.c - garbage collector for mruby -** -** See Copyright Notice in mruby.h -*/ - -#include <string.h> -#include <stdlib.h> -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/data.h> -#include <mruby/hash.h> -#include <mruby/proc.h> -#include <mruby/range.h> -#include <mruby/string.h> -#include <mruby/variable.h> -#include <mruby/gc.h> -#include <mruby/error.h> -#include <mruby/throw.h> - -/* - = Tri-color Incremental Garbage Collection - - mruby's GC is Tri-color Incremental GC with Mark & Sweep. - Algorithm details are omitted. - Instead, the implementation part is described below. - - == Object's Color - - Each object can be painted in three colors: - - * White - Unmarked. - * Gray - Marked, But the child objects are unmarked. - * Black - Marked, the child objects are also marked. - - == Two White Types - - There're two white color types in a flip-flop fashion: White-A and White-B, - which respectively represent the Current White color (the newly allocated - objects in the current GC cycle) and the Sweep Target White color (the - dead objects to be swept). - - A and B will be switched just at the beginning of the next GC cycle. At - that time, all the dead objects have been swept, while the newly created - objects in the current GC cycle which finally remains White are now - regarded as dead objects. Instead of traversing all the White-A objects and - painting them as White-B, just switch the meaning of White-A and White-B as - this will be much cheaper. - - As a result, the objects we sweep in the current GC cycle are always - left from the previous GC cycle. This allows us to sweep objects - incrementally, without the disturbance of the newly created objects. - - == Execution Timing - - GC Execution Time and Each step interval are decided by live objects count. - List of Adjustment API: - - * gc_interval_ratio_set - * gc_step_ratio_set - - For details, see the comments for each function. - - == Write Barrier - - mruby implementer and C extension library writer must insert a write - barrier when updating a reference from a field of an object. - When updating a reference from a field of object A to object B, - two different types of write barrier are available: - - * mrb_field_write_barrier - target B object for a mark. - * mrb_write_barrier - target A object for a mark. - - == Generational Mode - - mruby's GC offers an Generational Mode while re-using the tri-color GC - infrastructure. It will treat the Black objects as Old objects after each - sweep phase, instead of painting them White. The key ideas are still the same - as traditional generational GC: - - * Minor GC - just traverse the Young objects (Gray objects) in the mark - phase, then only sweep the newly created objects, and leave - the Old objects live. - - * Major GC - same as a full regular GC cycle. - - The difference from "traditional" generational GC is, that the major GC - in mruby is triggered incrementally in a tri-color manner. - - - For details, see the comments for each function. - -*/ - -struct free_obj { - MRB_OBJECT_HEADER; - struct RBasic *next; -}; - -typedef struct { - union { - struct free_obj free; - struct RBasic basic; - struct RObject object; - struct RClass klass; - struct RString string; - struct RArray array; - struct RHash hash; - struct RRange range; - struct RData data; - struct RProc proc; - struct REnv env; - struct RException exc; - struct RBreak brk; -#ifdef MRB_WORD_BOXING - struct RFloat floatv; - struct RCptr cptr; -#endif - } as; -} RVALUE; - -#ifdef GC_PROFILE -#include <stdio.h> -#include <sys/time.h> - -static double program_invoke_time = 0; -static double gc_time = 0; -static double gc_total_time = 0; - -static double -gettimeofday_time(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec * 1e-6; -} - -#define GC_INVOKE_TIME_REPORT(with) do {\ - fprintf(stderr, "%s\n", with);\ - fprintf(stderr, "gc_invoke: %19.3f\n", gettimeofday_time() - program_invoke_time);\ - fprintf(stderr, "is_generational: %d\n", is_generational(gc));\ - fprintf(stderr, "is_major_gc: %d\n", is_major_gc(gc));\ -} while(0) - -#define GC_TIME_START do {\ - gc_time = gettimeofday_time();\ -} while(0) - -#define GC_TIME_STOP_AND_REPORT do {\ - gc_time = gettimeofday_time() - gc_time;\ - gc_total_time += gc_time;\ - fprintf(stderr, "gc_state: %d\n", gc->state);\ - fprintf(stderr, "live: %zu\n", gc->live);\ - fprintf(stderr, "majorgc_old_threshold: %zu\n", gc->majorgc_old_threshold);\ - fprintf(stderr, "gc_threshold: %zu\n", gc->threshold);\ - fprintf(stderr, "gc_time: %30.20f\n", gc_time);\ - fprintf(stderr, "gc_total_time: %30.20f\n\n", gc_total_time);\ -} while(0) -#else -#define GC_INVOKE_TIME_REPORT(s) -#define GC_TIME_START -#define GC_TIME_STOP_AND_REPORT -#endif - -#ifdef GC_DEBUG -#define DEBUG(x) (x) -#else -#define DEBUG(x) -#endif - -#ifndef MRB_HEAP_PAGE_SIZE -#define MRB_HEAP_PAGE_SIZE 1024 -#endif - -#define GC_STEP_SIZE 1024 - -/* white: 011, black: 100, gray: 000 */ -#define GC_GRAY 0 -#define GC_WHITE_A 1 -#define GC_WHITE_B (1 << 1) -#define GC_BLACK (1 << 2) -#define GC_WHITES (GC_WHITE_A | GC_WHITE_B) -#define GC_COLOR_MASK 7 - -#define paint_gray(o) ((o)->color = GC_GRAY) -#define paint_black(o) ((o)->color = GC_BLACK) -#define paint_white(o) ((o)->color = GC_WHITES) -#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part) -#define is_gray(o) ((o)->color == GC_GRAY) -#define is_white(o) ((o)->color & GC_WHITES) -#define is_black(o) ((o)->color & GC_BLACK) -#define flip_white_part(s) ((s)->current_white_part = other_white_part(s)) -#define other_white_part(s) ((s)->current_white_part ^ GC_WHITES) -#define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE) - -#define objects(p) ((RVALUE *)p->objects) - -MRB_API void* -mrb_realloc_simple(mrb_state *mrb, void *p, size_t len) -{ - void *p2; - - p2 = (mrb->allocf)(mrb, p, len, mrb->allocf_ud); - if (!p2 && len > 0 && mrb->gc.heaps) { - mrb_full_gc(mrb); - p2 = (mrb->allocf)(mrb, p, len, mrb->allocf_ud); - } - - return p2; -} - -MRB_API void* -mrb_realloc(mrb_state *mrb, void *p, size_t len) -{ - void *p2; - - p2 = mrb_realloc_simple(mrb, p, len); - if (len == 0) return p2; - if (p2 == NULL) { - if (mrb->gc.out_of_memory) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); - /* mrb_panic(mrb); */ - } - else { - mrb->gc.out_of_memory = TRUE; - mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); - } - } - else { - mrb->gc.out_of_memory = FALSE; - } - - return p2; -} - -MRB_API void* -mrb_malloc(mrb_state *mrb, size_t len) -{ - return mrb_realloc(mrb, 0, len); -} - -MRB_API void* -mrb_malloc_simple(mrb_state *mrb, size_t len) -{ - return mrb_realloc_simple(mrb, 0, len); -} - -MRB_API void* -mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) -{ - void *p; - - if (nelem > 0 && len > 0 && - nelem <= SIZE_MAX / len) { - size_t size; - size = nelem * len; - p = mrb_malloc(mrb, size); - - memset(p, 0, size); - } - else { - p = NULL; - } - - return p; -} - -MRB_API void -mrb_free(mrb_state *mrb, void *p) -{ - (mrb->allocf)(mrb, p, 0, mrb->allocf_ud); -} - -MRB_API mrb_bool -mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) { - return is_dead(&mrb->gc, object); -} - -static void -link_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - page->next = gc->heaps; - if (gc->heaps) - gc->heaps->prev = page; - gc->heaps = page; -} - -static void -unlink_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - if (page->prev) - page->prev->next = page->next; - if (page->next) - page->next->prev = page->prev; - if (gc->heaps == page) - gc->heaps = page->next; - page->prev = NULL; - page->next = NULL; -} - -static void -link_free_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - page->free_next = gc->free_heaps; - if (gc->free_heaps) { - gc->free_heaps->free_prev = page; - } - gc->free_heaps = page; -} - -static void -unlink_free_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - if (page->free_prev) - page->free_prev->free_next = page->free_next; - if (page->free_next) - page->free_next->free_prev = page->free_prev; - if (gc->free_heaps == page) - gc->free_heaps = page->free_next; - page->free_prev = NULL; - page->free_next = NULL; -} - -static void -add_heap(mrb_state *mrb, mrb_gc *gc) -{ - mrb_heap_page *page = (mrb_heap_page *)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); - RVALUE *p, *e; - struct RBasic *prev = NULL; - - for (p = objects(page), e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) { - p->as.free.tt = MRB_TT_FREE; - p->as.free.next = prev; - prev = &p->as.basic; - } - page->freelist = prev; - - link_heap_page(gc, page); - link_free_heap_page(gc, page); -} - -#define DEFAULT_GC_INTERVAL_RATIO 200 -#define DEFAULT_GC_STEP_RATIO 200 -#define DEFAULT_MAJOR_GC_INC_RATIO 200 -#define is_generational(gc) ((gc)->generational) -#define is_major_gc(gc) (is_generational(gc) && (gc)->full) -#define is_minor_gc(gc) (is_generational(gc) && !(gc)->full) - -void -mrb_gc_init(mrb_state *mrb, mrb_gc *gc) -{ -#ifndef MRB_GC_FIXED_ARENA - gc->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE); - gc->arena_capa = MRB_GC_ARENA_SIZE; -#endif - - gc->current_white_part = GC_WHITE_A; - gc->heaps = NULL; - gc->free_heaps = NULL; - add_heap(mrb, gc); - gc->interval_ratio = DEFAULT_GC_INTERVAL_RATIO; - gc->step_ratio = DEFAULT_GC_STEP_RATIO; -#ifndef MRB_GC_TURN_OFF_GENERATIONAL - gc->generational = TRUE; - gc->full = TRUE; -#endif - -#ifdef GC_PROFILE - program_invoke_time = gettimeofday_time(); -#endif -} - -static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); - -void -free_heap(mrb_state *mrb, mrb_gc *gc) -{ - mrb_heap_page *page = gc->heaps; - mrb_heap_page *tmp; - RVALUE *p, *e; - - while (page) { - tmp = page; - page = page->next; - for (p = objects(tmp), e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) { - if (p->as.free.tt != MRB_TT_FREE) - obj_free(mrb, &p->as.basic, TRUE); - } - mrb_free(mrb, tmp); - } -} - -void -mrb_gc_destroy(mrb_state *mrb, mrb_gc *gc) -{ - free_heap(mrb, gc); -#ifndef MRB_GC_FIXED_ARENA - mrb_free(mrb, gc->arena); -#endif -} - -static void -gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) -{ -#ifdef MRB_GC_FIXED_ARENA - if (gc->arena_idx >= MRB_GC_ARENA_SIZE) { - /* arena overflow error */ - gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */ - mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err)); - } -#else - if (gc->arena_idx >= gc->arena_capa) { - /* extend arena */ - gc->arena_capa = (int)(gc->arena_capa * 1.5); - gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa); - } -#endif - gc->arena[gc->arena_idx++] = p; -} - -/* mrb_gc_protect() leaves the object in the arena */ -MRB_API void -mrb_gc_protect(mrb_state *mrb, mrb_value obj) -{ - if (mrb_immediate_p(obj)) return; - gc_protect(mrb, &mrb->gc, mrb_basic_ptr(obj)); -} - -#define GC_ROOT_NAME "_gc_root_" - -/* mrb_gc_register() keeps the object from GC. - - Register your object when it's exported to C world, - without reference from Ruby world, e.g. callback - arguments. Don't forget to remove the object using - mrb_gc_unregister, otherwise your object will leak. -*/ - -MRB_API void -mrb_gc_register(mrb_state *mrb, mrb_value obj) -{ - mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); - mrb_value table = mrb_gv_get(mrb, root); - - if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) { - table = mrb_ary_new(mrb); - mrb_gv_set(mrb, root, table); - } - mrb_ary_push(mrb, table, obj); -} - -/* mrb_gc_unregister() removes the object from GC root. */ -MRB_API void -mrb_gc_unregister(mrb_state *mrb, mrb_value obj) -{ - mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); - mrb_value table = mrb_gv_get(mrb, root); - struct RArray *a; - mrb_int i; - - if (mrb_nil_p(table)) return; - if (mrb_type(table) != MRB_TT_ARRAY) { - mrb_gv_set(mrb, root, mrb_nil_value()); - return; - } - a = mrb_ary_ptr(table); - mrb_ary_modify(mrb, a); - for (i = 0; i < ARY_LEN(a); i++) { - if (mrb_obj_eq(mrb, ARY_PTR(a)[i], obj)) { - mrb_int len = ARY_LEN(a)-1; - mrb_value *ptr = ARY_PTR(a); - - ARY_SET_LEN(a, len); - memmove(&ptr[i], &ptr[i + 1], (len - i) * sizeof(mrb_value)); - break; - } - } -} - -MRB_API struct RBasic* -mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) -{ - struct RBasic *p; - static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } }; - mrb_gc *gc = &mrb->gc; - - if (cls) { - enum mrb_vtype tt; - - switch (cls->tt) { - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - case MRB_TT_MODULE: - case MRB_TT_ENV: - break; - default: - mrb_raise(mrb, E_TYPE_ERROR, "allocation failure"); - } - tt = MRB_INSTANCE_TT(cls); - if (tt != MRB_TT_FALSE && - ttype != MRB_TT_SCLASS && - ttype != MRB_TT_ICLASS && - ttype != MRB_TT_ENV && - ttype != tt) { - mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls)); - } - } - -#ifdef MRB_GC_STRESS - mrb_full_gc(mrb); -#endif - if (gc->threshold < gc->live) { - mrb_incremental_gc(mrb); - } - if (gc->free_heaps == NULL) { - add_heap(mrb, gc); - } - - p = gc->free_heaps->freelist; - gc->free_heaps->freelist = ((struct free_obj*)p)->next; - if (gc->free_heaps->freelist == NULL) { - unlink_free_heap_page(gc, gc->free_heaps); - } - - gc->live++; - gc_protect(mrb, gc, p); - *(RVALUE *)p = RVALUE_zero; - p->tt = ttype; - p->c = cls; - paint_partial_white(gc, p); - return p; -} - -static inline void -add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) -{ -#ifdef MRB_GC_STRESS - if (obj->tt > MRB_TT_MAXDEFINE) { - abort(); - } -#endif - paint_gray(obj); - obj->gcnext = gc->gray_list; - gc->gray_list = obj; -} - -static void -mark_context_stack(mrb_state *mrb, struct mrb_context *c) -{ - size_t i; - size_t e; - mrb_value nil; - int nregs; - - if (c->stack == NULL) return; - e = c->stack - c->stbase; - if (c->ci) { - nregs = c->ci->argc + 2; - if (c->ci->nregs > nregs) - nregs = c->ci->nregs; - e += nregs; - } - if (c->stbase + e > c->stend) e = c->stend - c->stbase; - for (i=0; i<e; i++) { - mrb_value v = c->stbase[i]; - - if (!mrb_immediate_p(v)) { - mrb_gc_mark(mrb, mrb_basic_ptr(v)); - } - } - e = c->stend - c->stbase; - nil = mrb_nil_value(); - for (; i<e; i++) { - c->stbase[i] = nil; - } -} - -static void -mark_context(mrb_state *mrb, struct mrb_context *c) -{ - int i; - mrb_callinfo *ci; - - if (c->status == MRB_FIBER_TERMINATED) return; - - /* mark VM stack */ - mark_context_stack(mrb, c); - - /* mark call stack */ - if (c->cibase) { - for (ci = c->cibase; ci <= c->ci; ci++) { - mrb_gc_mark(mrb, (struct RBasic*)ci->env); - mrb_gc_mark(mrb, (struct RBasic*)ci->proc); - mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); - } - } - /* mark ensure stack */ - for (i=0; i<c->esize; i++) { - if (c->ensure[i] == NULL) break; - mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); - } - /* mark fibers */ - mrb_gc_mark(mrb, (struct RBasic*)c->fib); - if (c->prev) { - mark_context(mrb, c->prev); - } -} - -static void -gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) -{ - mrb_assert(is_gray(obj)); - paint_black(obj); - gc->gray_list = obj->gcnext; - mrb_gc_mark(mrb, (struct RBasic*)obj->c); - switch (obj->tt) { - case MRB_TT_ICLASS: - { - struct RClass *c = (struct RClass*)obj; - if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN)) - mrb_gc_mark_mt(mrb, c); - mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); - } - break; - - case MRB_TT_CLASS: - case MRB_TT_MODULE: - case MRB_TT_SCLASS: - { - struct RClass *c = (struct RClass*)obj; - - mrb_gc_mark_mt(mrb, c); - mrb_gc_mark(mrb, (struct RBasic*)c->super); - } - /* fall through */ - - case MRB_TT_OBJECT: - case MRB_TT_DATA: - case MRB_TT_EXCEPTION: - mrb_gc_mark_iv(mrb, (struct RObject*)obj); - break; - - case MRB_TT_PROC: - { - struct RProc *p = (struct RProc*)obj; - - mrb_gc_mark(mrb, (struct RBasic*)p->env); - mrb_gc_mark(mrb, (struct RBasic*)p->target_class); - if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { - mrb_gc_mark(mrb, (struct RBasic*)p->body.irep->target_class); - } - } - break; - - case MRB_TT_ENV: - { - struct REnv *e = (struct REnv*)obj; - mrb_int i, len; - - if (MRB_ENV_STACK_SHARED_P(e)) { - if (e->cxt.c->fib) { - mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib); - } - break; - } - len = MRB_ENV_STACK_LEN(e); - for (i=0; i<len; i++) { - mrb_gc_mark_value(mrb, e->stack[i]); - } - } - break; - - case MRB_TT_FIBER: - { - struct mrb_context *c = ((struct RFiber*)obj)->cxt; - - if (c) mark_context(mrb, c); - } - break; - - case MRB_TT_ARRAY: - { - struct RArray *a = (struct RArray*)obj; - size_t i, e; - - for (i=0,e=ARY_LEN(a); i<e; i++) { - mrb_gc_mark_value(mrb, ARY_PTR(a)[i]); - } - } - break; - - case MRB_TT_HASH: - mrb_gc_mark_iv(mrb, (struct RObject*)obj); - mrb_gc_mark_hash(mrb, (struct RHash*)obj); - break; - - case MRB_TT_STRING: - break; - - case MRB_TT_RANGE: - { - struct RRange *r = (struct RRange*)obj; - - if (r->edges) { - mrb_gc_mark_value(mrb, r->edges->beg); - mrb_gc_mark_value(mrb, r->edges->end); - } - } - break; - - default: - break; - } -} - -MRB_API void -mrb_gc_mark(mrb_state *mrb, struct RBasic *obj) -{ - if (obj == 0) return; - if (!is_white(obj)) return; - mrb_assert((obj)->tt != MRB_TT_FREE); - add_gray_list(mrb, &mrb->gc, obj); -} - -static void -obj_free(mrb_state *mrb, struct RBasic *obj, int end) -{ - DEBUG(fprintf(stderr, "obj_free(%p,tt=%d)\n",obj,obj->tt)); - switch (obj->tt) { - /* immediate - no mark */ - case MRB_TT_TRUE: - case MRB_TT_FIXNUM: - case MRB_TT_SYMBOL: - /* cannot happen */ - return; - - case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING - break; -#else - return; -#endif - - case MRB_TT_OBJECT: - mrb_gc_free_iv(mrb, (struct RObject*)obj); - break; - - case MRB_TT_EXCEPTION: - mrb_gc_free_iv(mrb, (struct RObject*)obj); - break; - - case MRB_TT_CLASS: - case MRB_TT_MODULE: - case MRB_TT_SCLASS: - mrb_gc_free_mt(mrb, (struct RClass*)obj); - mrb_gc_free_iv(mrb, (struct RObject*)obj); - break; - case MRB_TT_ICLASS: - if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN)) - mrb_gc_free_mt(mrb, (struct RClass*)obj); - break; - case MRB_TT_ENV: - { - struct REnv *e = (struct REnv*)obj; - - if (MRB_ENV_STACK_SHARED_P(e)) { - /* cannot be freed */ - return; - } - mrb_free(mrb, e->stack); - e->stack = NULL; - } - break; - - case MRB_TT_FIBER: - { - struct mrb_context *c = ((struct RFiber*)obj)->cxt; - - if (!end && c && c != mrb->root_c) { - mrb_callinfo *ci = c->ci; - mrb_callinfo *ce = c->cibase; - - while (ce <= ci) { - struct REnv *e = ci->env; - if (e && !is_dead(&mrb->gc, e) && - e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { - mrb_env_unshare(mrb, e); - } - ci--; - } - mrb_free_context(mrb, c); - } - } - break; - - case MRB_TT_ARRAY: - if (ARY_SHARED_P(obj)) - mrb_ary_decref(mrb, ((struct RArray*)obj)->as.heap.aux.shared); - else if (!ARY_EMBED_P(obj)) - mrb_free(mrb, ((struct RArray*)obj)->as.heap.ptr); - break; - - case MRB_TT_HASH: - mrb_gc_free_iv(mrb, (struct RObject*)obj); - mrb_gc_free_hash(mrb, (struct RHash*)obj); - break; - - case MRB_TT_STRING: - mrb_gc_free_str(mrb, (struct RString*)obj); - break; - - case MRB_TT_PROC: - { - struct RProc *p = (struct RProc*)obj; - - if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { - mrb_irep_decref(mrb, p->body.irep); - } - } - break; - - case MRB_TT_RANGE: - mrb_free(mrb, ((struct RRange*)obj)->edges); - break; - - case MRB_TT_DATA: - { - struct RData *d = (struct RData*)obj; - if (d->type && d->type->dfree) { - d->type->dfree(mrb, d->data); - } - mrb_gc_free_iv(mrb, (struct RObject*)obj); - } - break; - - default: - break; - } - obj->tt = MRB_TT_FREE; -} - -static void -root_scan_phase(mrb_state *mrb, mrb_gc *gc) -{ - int i, e; - - if (!is_minor_gc(gc)) { - gc->gray_list = NULL; - gc->atomic_gray_list = NULL; - } - - mrb_gc_mark_gv(mrb); - /* mark arena */ - for (i=0,e=gc->arena_idx; i<e; i++) { - mrb_gc_mark(mrb, gc->arena[i]); - } - /* mark class hierarchy */ - mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class); - - /* mark built-in classes */ - mrb_gc_mark(mrb, (struct RBasic*)mrb->class_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->module_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->proc_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->string_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class); - - mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->nil_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->symbol_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->kernel_module); - - mrb_gc_mark(mrb, (struct RBasic*)mrb->eException_class); - mrb_gc_mark(mrb, (struct RBasic*)mrb->eStandardError_class); - - /* mark top_self */ - mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self); - /* mark exception */ - mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); - /* mark pre-allocated exception */ - mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err); - mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err); -#ifdef MRB_GC_FIXED_ARENA - mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); -#endif - - mark_context(mrb, mrb->c); - if (mrb->root_c != mrb->c) { - mark_context(mrb, mrb->root_c); - } -} - -static size_t -gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) -{ - size_t children = 0; - - gc_mark_children(mrb, gc, obj); - - switch (obj->tt) { - case MRB_TT_ICLASS: - children++; - break; - - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - case MRB_TT_MODULE: - { - struct RClass *c = (struct RClass*)obj; - - children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); - children += mrb_gc_mark_mt_size(mrb, c); - children++; - } - break; - - case MRB_TT_OBJECT: - case MRB_TT_DATA: - case MRB_TT_EXCEPTION: - children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); - break; - - case MRB_TT_ENV: - children += (int)obj->flags; - break; - - case MRB_TT_FIBER: - { - struct mrb_context *c = ((struct RFiber*)obj)->cxt; - size_t i; - mrb_callinfo *ci; - - if (!c) break; - /* mark stack */ - i = c->stack - c->stbase; - if (c->ci) i += c->ci->nregs; - if (c->stbase + i > c->stend) i = c->stend - c->stbase; - children += i; - - /* mark ensure stack */ - children += c->eidx; - - /* mark closure */ - if (c->cibase) { - for (i=0, ci = c->cibase; ci <= c->ci; i++, ci++) - ; - } - children += i; - } - break; - - case MRB_TT_ARRAY: - { - struct RArray *a = (struct RArray*)obj; - children += ARY_LEN(a); - } - break; - - case MRB_TT_HASH: - children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); - children += mrb_gc_mark_hash_size(mrb, (struct RHash*)obj); - break; - - case MRB_TT_PROC: - case MRB_TT_RANGE: - children+=2; - break; - - default: - break; - } - return children; -} - - -static void -gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) { - while (gc->gray_list) { - if (is_gray(gc->gray_list)) - gc_mark_children(mrb, gc, gc->gray_list); - else - gc->gray_list = gc->gray_list->gcnext; - } -} - - -static size_t -incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) -{ - size_t tried_marks = 0; - - while (gc->gray_list && tried_marks < limit) { - tried_marks += gc_gray_mark(mrb, gc, gc->gray_list); - } - - return tried_marks; -} - -static void -final_marking_phase(mrb_state *mrb, mrb_gc *gc) -{ - int i, e; - - /* mark arena */ - for (i=0,e=gc->arena_idx; i<e; i++) { - mrb_gc_mark(mrb, gc->arena[i]); - } - mrb_gc_mark_gv(mrb); - mark_context(mrb, mrb->c); - mark_context(mrb, mrb->root_c); - mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); - gc_mark_gray_list(mrb, gc); - mrb_assert(gc->gray_list == NULL); - gc->gray_list = gc->atomic_gray_list; - gc->atomic_gray_list = NULL; - gc_mark_gray_list(mrb, gc); - mrb_assert(gc->gray_list == NULL); -} - -static void -prepare_incremental_sweep(mrb_state *mrb, mrb_gc *gc) -{ - gc->state = MRB_GC_STATE_SWEEP; - gc->sweeps = gc->heaps; - gc->live_after_mark = gc->live; -} - -static size_t -incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) -{ - mrb_heap_page *page = gc->sweeps; - size_t tried_sweep = 0; - - while (page && (tried_sweep < limit)) { - RVALUE *p = objects(page); - RVALUE *e = p + MRB_HEAP_PAGE_SIZE; - size_t freed = 0; - mrb_bool dead_slot = TRUE; - mrb_bool full = (page->freelist == NULL); - - if (is_minor_gc(gc) && page->old) { - /* skip a slot which doesn't contain any young object */ - p = e; - dead_slot = FALSE; - } - while (p<e) { - if (is_dead(gc, &p->as.basic)) { - if (p->as.basic.tt != MRB_TT_FREE) { - obj_free(mrb, &p->as.basic, FALSE); - if (p->as.basic.tt == MRB_TT_FREE) { - p->as.free.next = page->freelist; - page->freelist = (struct RBasic*)p; - freed++; - } - else { - dead_slot = FALSE; - } - } - } - else { - if (!is_generational(gc)) - paint_partial_white(gc, &p->as.basic); /* next gc target */ - dead_slot = FALSE; - } - p++; - } - - /* free dead slot */ - if (dead_slot && freed < MRB_HEAP_PAGE_SIZE) { - mrb_heap_page *next = page->next; - - unlink_heap_page(gc, page); - unlink_free_heap_page(gc, page); - mrb_free(mrb, page); - page = next; - } - else { - if (full && freed > 0) { - link_free_heap_page(gc, page); - } - if (page->freelist == NULL && is_minor_gc(gc)) - page->old = TRUE; - else - page->old = FALSE; - page = page->next; - } - tried_sweep += MRB_HEAP_PAGE_SIZE; - gc->live -= freed; - gc->live_after_mark -= freed; - } - gc->sweeps = page; - return tried_sweep; -} - -static size_t -incremental_gc(mrb_state *mrb, mrb_gc *gc, size_t limit) -{ - switch (gc->state) { - case MRB_GC_STATE_ROOT: - root_scan_phase(mrb, gc); - gc->state = MRB_GC_STATE_MARK; - flip_white_part(gc); - return 0; - case MRB_GC_STATE_MARK: - if (gc->gray_list) { - return incremental_marking_phase(mrb, gc, limit); - } - else { - final_marking_phase(mrb, gc); - prepare_incremental_sweep(mrb, gc); - return 0; - } - case MRB_GC_STATE_SWEEP: { - size_t tried_sweep = 0; - tried_sweep = incremental_sweep_phase(mrb, gc, limit); - if (tried_sweep == 0) - gc->state = MRB_GC_STATE_ROOT; - return tried_sweep; - } - default: - /* unknown state */ - mrb_assert(0); - return 0; - } -} - -static void -incremental_gc_until(mrb_state *mrb, mrb_gc *gc, mrb_gc_state to_state) -{ - do { - incremental_gc(mrb, gc, SIZE_MAX); - } while (gc->state != to_state); -} - -static void -incremental_gc_step(mrb_state *mrb, mrb_gc *gc) -{ - size_t limit = 0, result = 0; - limit = (GC_STEP_SIZE/100) * gc->step_ratio; - while (result < limit) { - result += incremental_gc(mrb, gc, limit); - if (gc->state == MRB_GC_STATE_ROOT) - break; - } - - gc->threshold = gc->live + GC_STEP_SIZE; -} - -static void -clear_all_old(mrb_state *mrb, mrb_gc *gc) -{ - mrb_bool origin_mode = gc->generational; - - mrb_assert(is_generational(gc)); - if (is_major_gc(gc)) { - /* finish the half baked GC */ - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); - } - - /* Sweep the dead objects, then reset all the live objects - * (including all the old objects, of course) to white. */ - gc->generational = FALSE; - prepare_incremental_sweep(mrb, gc); - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); - gc->generational = origin_mode; - - /* The gray objects have already been painted as white */ - gc->atomic_gray_list = gc->gray_list = NULL; -} - -MRB_API void -mrb_incremental_gc(mrb_state *mrb) -{ - mrb_gc *gc = &mrb->gc; - - if (gc->disabled || gc->iterating) return; - - GC_INVOKE_TIME_REPORT("mrb_incremental_gc()"); - GC_TIME_START; - - if (is_minor_gc(gc)) { - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); - } - else { - incremental_gc_step(mrb, gc); - } - - if (gc->state == MRB_GC_STATE_ROOT) { - mrb_assert(gc->live >= gc->live_after_mark); - gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio; - if (gc->threshold < GC_STEP_SIZE) { - gc->threshold = GC_STEP_SIZE; - } - - if (is_major_gc(gc)) { - gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; - gc->full = FALSE; - } - else if (is_minor_gc(gc)) { - if (gc->live > gc->majorgc_old_threshold) { - clear_all_old(mrb, gc); - gc->full = TRUE; - } - } - } - - GC_TIME_STOP_AND_REPORT; -} - -/* Perform a full gc cycle */ -MRB_API void -mrb_full_gc(mrb_state *mrb) -{ - mrb_gc *gc = &mrb->gc; - - if (gc->disabled || gc->iterating) return; - - GC_INVOKE_TIME_REPORT("mrb_full_gc()"); - GC_TIME_START; - - if (is_generational(gc)) { - /* clear all the old objects back to young */ - clear_all_old(mrb, gc); - gc->full = TRUE; - } - else if (gc->state != MRB_GC_STATE_ROOT) { - /* finish half baked GC cycle */ - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); - } - - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); - gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio; - - if (is_generational(gc)) { - gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; - gc->full = FALSE; - } - - GC_TIME_STOP_AND_REPORT; -} - -MRB_API void -mrb_garbage_collect(mrb_state *mrb) -{ - mrb_full_gc(mrb); -} - -/* - * Field write barrier - * Paint obj(Black) -> value(White) to obj(Black) -> value(Gray). - */ - -MRB_API void -mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value) -{ - mrb_gc *gc = &mrb->gc; - - if (!is_black(obj)) return; - if (!is_white(value)) return; - - mrb_assert(gc->state == MRB_GC_STATE_MARK || (!is_dead(gc, value) && !is_dead(gc, obj))); - mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); - - if (is_generational(gc) || gc->state == MRB_GC_STATE_MARK) { - add_gray_list(mrb, gc, value); - } - else { - mrb_assert(gc->state == MRB_GC_STATE_SWEEP); - paint_partial_white(gc, obj); /* for never write barriers */ - } -} - -/* - * Write barrier - * Paint obj(Black) to obj(Gray). - * - * The object that is painted gray will be traversed atomically in final - * mark phase. So you use this write barrier if it's frequency written spot. - * e.g. Set element on Array. - */ - -MRB_API void -mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) -{ - mrb_gc *gc = &mrb->gc; - - if (!is_black(obj)) return; - - mrb_assert(!is_dead(gc, obj)); - mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); - paint_gray(obj); - obj->gcnext = gc->atomic_gray_list; - gc->atomic_gray_list = obj; -} - -/* - * call-seq: - * GC.start -> nil - * - * Initiates full garbage collection. - * - */ - -static mrb_value -gc_start(mrb_state *mrb, mrb_value obj) -{ - mrb_full_gc(mrb); - return mrb_nil_value(); -} - -/* - * call-seq: - * GC.enable -> true or false - * - * Enables garbage collection, returning <code>true</code> if garbage - * collection was previously disabled. - * - * GC.disable #=> false - * GC.enable #=> true - * GC.enable #=> false - * - */ - -static mrb_value -gc_enable(mrb_state *mrb, mrb_value obj) -{ - mrb_bool old = mrb->gc.disabled; - - mrb->gc.disabled = FALSE; - - return mrb_bool_value(old); -} - -/* - * call-seq: - * GC.disable -> true or false - * - * Disables garbage collection, returning <code>true</code> if garbage - * collection was already disabled. - * - * GC.disable #=> false - * GC.disable #=> true - * - */ - -static mrb_value -gc_disable(mrb_state *mrb, mrb_value obj) -{ - mrb_bool old = mrb->gc.disabled; - - mrb->gc.disabled = TRUE; - - return mrb_bool_value(old); -} - -/* - * call-seq: - * GC.interval_ratio -> fixnum - * - * Returns ratio of GC interval. Default value is 200(%). - * - */ - -static mrb_value -gc_interval_ratio_get(mrb_state *mrb, mrb_value obj) -{ - return mrb_fixnum_value(mrb->gc.interval_ratio); -} - -/* - * call-seq: - * GC.interval_ratio = fixnum -> nil - * - * Updates ratio of GC interval. Default value is 200(%). - * GC start as soon as after end all step of GC if you set 100(%). - * - */ - -static mrb_value -gc_interval_ratio_set(mrb_state *mrb, mrb_value obj) -{ - mrb_int ratio; - - mrb_get_args(mrb, "i", &ratio); - mrb->gc.interval_ratio = ratio; - return mrb_nil_value(); -} - -/* - * call-seq: - * GC.step_ratio -> fixnum - * - * Returns step span ratio of Incremental GC. Default value is 200(%). - * - */ - -static mrb_value -gc_step_ratio_get(mrb_state *mrb, mrb_value obj) -{ - return mrb_fixnum_value(mrb->gc.step_ratio); -} - -/* - * call-seq: - * GC.step_ratio = fixnum -> nil - * - * Updates step span ratio of Incremental GC. Default value is 200(%). - * 1 step of incrementalGC becomes long if a rate is big. - * - */ - -static mrb_value -gc_step_ratio_set(mrb_state *mrb, mrb_value obj) -{ - mrb_int ratio; - - mrb_get_args(mrb, "i", &ratio); - mrb->gc.step_ratio = ratio; - return mrb_nil_value(); -} - -static void -change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable) -{ - if (gc->disabled || gc->iterating) { - mrb_raise(mrb, E_RUNTIME_ERROR, "generational mode changed when GC disabled"); - return; - } - if (is_generational(gc) && !enable) { - clear_all_old(mrb, gc); - mrb_assert(gc->state == MRB_GC_STATE_ROOT); - gc->full = FALSE; - } - else if (!is_generational(gc) && enable) { - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); - gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; - gc->full = FALSE; - } - gc->generational = enable; -} - -/* - * call-seq: - * GC.generational_mode -> true or false - * - * Returns generational or normal gc mode. - * - */ - -static mrb_value -gc_generational_mode_get(mrb_state *mrb, mrb_value self) -{ - return mrb_bool_value(mrb->gc.generational); -} - -/* - * call-seq: - * GC.generational_mode = true or false -> true or false - * - * Changes to generational or normal gc mode. - * - */ - -static mrb_value -gc_generational_mode_set(mrb_state *mrb, mrb_value self) -{ - mrb_bool enable; - - mrb_get_args(mrb, "b", &enable); - if (mrb->gc.generational != enable) - change_gen_gc_mode(mrb, &mrb->gc, enable); - - return mrb_bool_value(enable); -} - - -static void -gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, void *data) -{ - mrb_heap_page* page; - - mrb_full_gc(mrb); - page = gc->heaps; - while (page != NULL) { - RVALUE *p; - int i; - - p = objects(page); - for (i=0; i < MRB_HEAP_PAGE_SIZE; i++) { - if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK) - return; - } - page = page->next; - } -} - -void -mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data) -{ - mrb_bool iterating = mrb->gc.iterating; - - mrb->gc.iterating = TRUE; - if (iterating) { - gc_each_objects(mrb, &mrb->gc, callback, data); - } - else { - struct mrb_jmpbuf *prev_jmp = mrb->jmp; - struct mrb_jmpbuf c_jmp; - - MRB_TRY(&c_jmp) { - mrb->jmp = &c_jmp; - gc_each_objects(mrb, &mrb->gc, callback, data); - mrb->jmp = prev_jmp; - mrb->gc.iterating = iterating; - } MRB_CATCH(&c_jmp) { - mrb->gc.iterating = iterating; - mrb->jmp = prev_jmp; - MRB_THROW(prev_jmp); - } MRB_END_EXC(&c_jmp); - } -} - -#ifdef GC_TEST -#ifdef GC_DEBUG -static mrb_value gc_test(mrb_state *, mrb_value); -#endif -#endif - -void -mrb_init_gc(mrb_state *mrb) -{ - struct RClass *gc; - - gc = mrb_define_module(mrb, "GC"); - - mrb_define_class_method(mrb, gc, "start", gc_start, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, gc, "enable", gc_enable, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, gc, "disable", gc_disable, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, gc, "interval_ratio", gc_interval_ratio_get, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, gc, "interval_ratio=", gc_interval_ratio_set, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, gc, "step_ratio", gc_step_ratio_get, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, gc, "step_ratio=", gc_step_ratio_set, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, gc, "generational_mode=", gc_generational_mode_set, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, gc, "generational_mode", gc_generational_mode_get, MRB_ARGS_NONE()); -#ifdef GC_TEST -#ifdef GC_DEBUG - mrb_define_class_method(mrb, gc, "test", gc_test, MRB_ARGS_NONE()); -#endif -#endif -} - -#ifdef GC_TEST -#ifdef GC_DEBUG -void -test_mrb_field_write_barrier(void) -{ - mrb_state *mrb = mrb_open(); - struct RBasic *obj, *value; - mrb_gc *gc = &mrb->gc; - - puts("test_mrb_field_write_barrier"); - gc->generational = FALSE; - obj = mrb_basic_ptr(mrb_ary_new(mrb)); - value = mrb_basic_ptr(mrb_str_new_lit(mrb, "value")); - paint_black(obj); - paint_partial_white(gc, value); - - - puts(" in MRB_GC_STATE_MARK"); - gc->state = MRB_GC_STATE_MARK; - mrb_field_write_barrier(mrb, obj, value); - - mrb_assert(is_gray(value)); - - - puts(" in MRB_GC_STATE_SWEEP"); - paint_partial_white(gc, value); - gc->state = MRB_GC_STATE_SWEEP; - mrb_field_write_barrier(mrb, obj, value); - - mrb_assert(obj->color & gc->current_white_part); - mrb_assert(value->color & gc->current_white_part); - - - puts(" fail with black"); - gc->state = MRB_GC_STATE_MARK; - paint_white(obj); - paint_partial_white(gc, value); - mrb_field_write_barrier(mrb, obj, value); - - mrb_assert(obj->color & gc->current_white_part); - - - puts(" fail with gray"); - gc->state = MRB_GC_STATE_MARK; - paint_black(obj); - paint_gray(value); - mrb_field_write_barrier(mrb, obj, value); - - mrb_assert(is_gray(value)); - - - { - puts("test_mrb_field_write_barrier_value"); - obj = mrb_basic_ptr(mrb_ary_new(mrb)); - mrb_value value = mrb_str_new_lit(mrb, "value"); - paint_black(obj); - paint_partial_white(gc, mrb_basic_ptr(value)); - - gc->state = MRB_GC_STATE_MARK; - mrb_field_write_barrier_value(mrb, obj, value); - - mrb_assert(is_gray(mrb_basic_ptr(value))); - } - - mrb_close(mrb); -} - -void -test_mrb_write_barrier(void) -{ - mrb_state *mrb = mrb_open(); - struct RBasic *obj; - mrb_gc *gc = &mrb->gc; - - puts("test_mrb_write_barrier"); - obj = mrb_basic_ptr(mrb_ary_new(mrb)); - paint_black(obj); - - puts(" in MRB_GC_STATE_MARK"); - gc->state = MRB_GC_STATE_MARK; - mrb_write_barrier(mrb, obj); - - mrb_assert(is_gray(obj)); - mrb_assert(gc->atomic_gray_list == obj); - - - puts(" fail with gray"); - paint_gray(obj); - mrb_write_barrier(mrb, obj); - - mrb_assert(is_gray(obj)); - - mrb_close(mrb); -} - -void -test_add_gray_list(void) -{ - mrb_state *mrb = mrb_open(); - struct RBasic *obj1, *obj2; - mrb_gc *gc = &mrb->gc; - - puts("test_add_gray_list"); - change_gen_gc_mode(mrb, gc, FALSE); - mrb_assert(gc->gray_list == NULL); - obj1 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test")); - add_gray_list(mrb, gc, obj1); - mrb_assert(gc->gray_list == obj1); - mrb_assert(is_gray(obj1)); - - obj2 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test")); - add_gray_list(mrb, gc, obj2); - mrb_assert(gc->gray_list == obj2); - mrb_assert(gc->gray_list->gcnext == obj1); - mrb_assert(is_gray(obj2)); - - mrb_close(mrb); -} - -void -test_gc_gray_mark(void) -{ - mrb_state *mrb = mrb_open(); - mrb_value obj_v, value_v; - struct RBasic *obj; - size_t gray_num = 0; - mrb_gc *gc = &mrb->gc; - - puts("test_gc_gray_mark"); - - puts(" in MRB_TT_CLASS"); - obj = (struct RBasic*)mrb->object_class; - paint_gray(obj); - gray_num = gc_gray_mark(mrb, gc, obj); - mrb_assert(is_black(obj)); - mrb_assert(gray_num > 1); - - puts(" in MRB_TT_ARRAY"); - obj_v = mrb_ary_new(mrb); - value_v = mrb_str_new_lit(mrb, "test"); - paint_gray(mrb_basic_ptr(obj_v)); - paint_partial_white(gc, mrb_basic_ptr(value_v)); - mrb_ary_push(mrb, obj_v, value_v); - gray_num = gc_gray_mark(mrb, gc, mrb_basic_ptr(obj_v)); - mrb_assert(is_black(mrb_basic_ptr(obj_v))); - mrb_assert(is_gray(mrb_basic_ptr(value_v))); - mrb_assert(gray_num == 1); - - mrb_close(mrb); -} - -void -test_incremental_gc(void) -{ - mrb_state *mrb = mrb_open(); - size_t max = ~0, live = 0, total = 0, freed = 0; - RVALUE *free; - mrb_heap_page *page; - mrb_gc *gc = &mrb->gc; - - puts("test_incremental_gc"); - change_gen_gc_mode(mrb, gc, FALSE); - - puts(" in mrb_full_gc"); - mrb_full_gc(mrb); - - mrb_assert(gc->state == MRB_GC_STATE_ROOT); - puts(" in MRB_GC_STATE_ROOT"); - incremental_gc(mrb, gc, max); - mrb_assert(gc->state == MRB_GC_STATE_MARK); - puts(" in MRB_GC_STATE_MARK"); - incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP); - mrb_assert(gc->state == MRB_GC_STATE_SWEEP); - - puts(" in MRB_GC_STATE_SWEEP"); - page = gc->heaps; - while (page) { - RVALUE *p = objects(page); - RVALUE *e = p + MRB_HEAP_PAGE_SIZE; - while (p<e) { - if (is_black(&p->as.basic)) { - live++; - } - if (is_gray(&p->as.basic) && !is_dead(gc, &p->as.basic)) { - printf("%p\n", &p->as.basic); - } - p++; - } - page = page->next; - total += MRB_HEAP_PAGE_SIZE; - } - - mrb_assert(gc->gray_list == NULL); - - incremental_gc(mrb, gc, max); - mrb_assert(gc->state == MRB_GC_STATE_SWEEP); - - incremental_gc(mrb, gc, max); - mrb_assert(gc->state == MRB_GC_STATE_ROOT); - - free = (RVALUE*)gc->heaps->freelist; - while (free) { - freed++; - free = (RVALUE*)free->as.free.next; - } - - mrb_assert(gc->live == live); - mrb_assert(gc->live == total-freed); - - puts("test_incremental_gc(gen)"); - incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP); - change_gen_gc_mode(mrb, gc, TRUE); - - mrb_assert(gc->full == FALSE); - mrb_assert(gc->state == MRB_GC_STATE_ROOT); - - puts(" in minor"); - mrb_assert(is_minor_gc(gc)); - mrb_assert(gc->majorgc_old_threshold > 0); - gc->majorgc_old_threshold = 0; - mrb_incremental_gc(mrb); - mrb_assert(gc->full == TRUE); - mrb_assert(gc->state == MRB_GC_STATE_ROOT); - - puts(" in major"); - mrb_assert(is_major_gc(gc)); - do { - mrb_incremental_gc(mrb); - } while (gc->state != MRB_GC_STATE_ROOT); - mrb_assert(gc->full == FALSE); - - mrb_close(mrb); -} - -void -test_incremental_sweep_phase(void) -{ - mrb_state *mrb = mrb_open(); - mrb_gc *gc = &mrb->gc; - - puts("test_incremental_sweep_phase"); - - add_heap(mrb, gc); - gc->sweeps = gc->heaps; - - mrb_assert(gc->heaps->next->next == NULL); - mrb_assert(gc->free_heaps->next->next == NULL); - incremental_sweep_phase(mrb, gc, MRB_HEAP_PAGE_SIZE * 3); - - mrb_assert(gc->heaps->next == NULL); - mrb_assert(gc->heaps == gc->free_heaps); - - mrb_close(mrb); -} - -static mrb_value -gc_test(mrb_state *mrb, mrb_value self) -{ - test_mrb_field_write_barrier(); - test_mrb_write_barrier(); - test_add_gray_list(); - test_gc_gray_mark(); - test_incremental_gc(); - test_incremental_sweep_phase(); - return mrb_nil_value(); -} -#endif /* GC_DEBUG */ -#endif /* GC_TEST */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/hash.c b/web/server/h2o/libh2o/deps/mruby/src/hash.c deleted file mode 100644 index 93d550187..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/hash.c +++ /dev/null @@ -1,905 +0,0 @@ -/* -** hash.c - Hash class -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/hash.h> -#include <mruby/khash.h> -#include <mruby/string.h> -#include <mruby/variable.h> - -/* a function to get hash value of a float number */ -mrb_int mrb_float_id(mrb_float f); - -static inline khint_t -mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key) -{ - enum mrb_vtype t = mrb_type(key); - mrb_value hv; - khint_t h; - - switch (t) { - case MRB_TT_STRING: - h = mrb_str_hash(mrb, key); - break; - - case MRB_TT_TRUE: - case MRB_TT_FALSE: - case MRB_TT_SYMBOL: - case MRB_TT_FIXNUM: - case MRB_TT_FLOAT: - h = (khint_t)mrb_obj_id(key); - break; - - default: - hv = mrb_funcall(mrb, key, "hash", 0); - h = (khint_t)t ^ mrb_fixnum(hv); - break; - } - return kh_int_hash_func(mrb, h); -} - -static inline khint_t -mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b) -{ - enum mrb_vtype t = mrb_type(a); - - switch (t) { - case MRB_TT_STRING: - return mrb_str_equal(mrb, a, b); - - case MRB_TT_SYMBOL: - if (mrb_type(b) != MRB_TT_SYMBOL) return FALSE; - return mrb_symbol(a) == mrb_symbol(b); - - case MRB_TT_FIXNUM: - switch (mrb_type(b)) { - case MRB_TT_FIXNUM: - return mrb_fixnum(a) == mrb_fixnum(b); - case MRB_TT_FLOAT: - return (mrb_float)mrb_fixnum(a) == mrb_float(b); - default: - return FALSE; - } - - case MRB_TT_FLOAT: - switch (mrb_type(b)) { - case MRB_TT_FIXNUM: - return mrb_float(a) == (mrb_float)mrb_fixnum(b); - case MRB_TT_FLOAT: - return mrb_float(a) == mrb_float(b); - default: - return FALSE; - } - - default: - return mrb_eql(mrb, a, b); - } -} - -KHASH_DEFINE (ht, mrb_value, mrb_hash_value, TRUE, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal) - -static void mrb_hash_modify(mrb_state *mrb, mrb_value hash); - -static inline mrb_value -mrb_hash_ht_key(mrb_state *mrb, mrb_value key) -{ - if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) { - key = mrb_str_dup(mrb, key); - MRB_SET_FROZEN_FLAG(mrb_str_ptr(key)); - } - return key; -} - -#define KEY(key) mrb_hash_ht_key(mrb, key) - -void -mrb_gc_mark_hash(mrb_state *mrb, struct RHash *hash) -{ - khiter_t k; - khash_t(ht) *h = hash->ht; - - if (!h) return; - for (k = kh_begin(h); k != kh_end(h); k++) { - if (kh_exist(h, k)) { - mrb_value key = kh_key(h, k); - mrb_value val = kh_value(h, k).v; - - mrb_gc_mark_value(mrb, key); - mrb_gc_mark_value(mrb, val); - } - } -} - -size_t -mrb_gc_mark_hash_size(mrb_state *mrb, struct RHash *hash) -{ - if (!hash->ht) return 0; - return kh_size(hash->ht)*2; -} - -void -mrb_gc_free_hash(mrb_state *mrb, struct RHash *hash) -{ - if (hash->ht) kh_destroy(ht, mrb, hash->ht); -} - - -MRB_API mrb_value -mrb_hash_new_capa(mrb_state *mrb, mrb_int capa) -{ - struct RHash *h; - - h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); - /* khash needs 1/4 empty space so it is not resized immediately */ - h->ht = kh_init_size(ht, mrb, capa*4/3); - h->iv = 0; - return mrb_obj_value(h); -} - -MRB_API mrb_value -mrb_hash_new(mrb_state *mrb) -{ - return mrb_hash_new_capa(mrb, 0); -} - -static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash); -static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key); - -MRB_API mrb_value -mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) -{ - khash_t(ht) *h = RHASH_TBL(hash); - khiter_t k; - mrb_sym mid; - - if (h) { - k = kh_get(ht, mrb, h, key); - if (k != kh_end(h)) - return kh_value(h, k).v; - } - - mid = mrb_intern_lit(mrb, "default"); - if (mrb_func_basic_p(mrb, hash, mid, mrb_hash_default)) { - return hash_default(mrb, hash, key); - } - /* xxx mrb_funcall_tailcall(mrb, hash, "default", 1, key); */ - return mrb_funcall_argv(mrb, hash, mid, 1, &key); -} - -MRB_API mrb_value -mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def) -{ - khash_t(ht) *h = RHASH_TBL(hash); - khiter_t k; - - if (h) { - k = kh_get(ht, mrb, h, key); - if (k != kh_end(h)) - return kh_value(h, k).v; - } - - /* not found */ - return def; -} - -MRB_API void -mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) -{ - khash_t(ht) *h; - khiter_t k; - int r; - - mrb_hash_modify(mrb, hash); - h = RHASH_TBL(hash); - - if (!h) h = RHASH_TBL(hash) = kh_init(ht, mrb); - k = kh_put2(ht, mrb, h, key, &r); - kh_value(h, k).v = val; - - if (r != 0) { - /* expand */ - int ai = mrb_gc_arena_save(mrb); - key = kh_key(h, k) = KEY(key); - mrb_gc_arena_restore(mrb, ai); - kh_value(h, k).n = kh_size(h)-1; - } - - mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), key); - mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), val); - return; -} - -static mrb_value -mrb_hash_dup(mrb_state *mrb, mrb_value hash) -{ - struct RHash* ret; - khash_t(ht) *h, *ret_h; - khiter_t k, ret_k; - mrb_value ifnone, vret; - - h = RHASH_TBL(hash); - ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); - ret->ht = kh_init(ht, mrb); - - if (h && kh_size(h) > 0) { - ret_h = ret->ht; - - for (k = kh_begin(h); k != kh_end(h); k++) { - if (kh_exist(h, k)) { - int ai = mrb_gc_arena_save(mrb); - ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k))); - mrb_gc_arena_restore(mrb, ai); - kh_val(ret_h, ret_k).v = kh_val(h, k).v; - kh_val(ret_h, ret_k).n = kh_size(ret_h)-1; - } - } - } - - if (MRB_RHASH_DEFAULT_P(hash)) { - ret->flags |= MRB_HASH_DEFAULT; - } - if (MRB_RHASH_PROCDEFAULT_P(hash)) { - ret->flags |= MRB_HASH_PROC_DEFAULT; - } - vret = mrb_obj_value(ret); - ifnone = RHASH_IFNONE(hash); - if (!mrb_nil_p(ifnone)) { - mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone); - } - return vret; -} - -MRB_API mrb_value -mrb_check_hash_type(mrb_state *mrb, mrb_value hash) -{ - return mrb_check_convert_type(mrb, hash, MRB_TT_HASH, "Hash", "to_hash"); -} - -MRB_API khash_t(ht)* -mrb_hash_tbl(mrb_state *mrb, mrb_value hash) -{ - khash_t(ht) *h = RHASH_TBL(hash); - - if (!h) { - return RHASH_TBL(hash) = kh_init(ht, mrb); - } - return h; -} - -static void -mrb_hash_modify(mrb_state *mrb, mrb_value hash) -{ - if (MRB_FROZEN_P(mrb_hash_ptr(hash))) { - mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash"); - } - mrb_hash_tbl(mrb, hash); -} - -/* 15.2.13.4.16 */ -/* - * call-seq: - * Hash.new -> new_hash - * Hash.new(obj) -> new_hash - * Hash.new {|hash, key| block } -> new_hash - * - * Returns a new, empty hash. If this hash is subsequently accessed by - * a key that doesn't correspond to a hash entry, the value returned - * depends on the style of <code>new</code> used to create the hash. In - * the first form, the access returns <code>nil</code>. If - * <i>obj</i> is specified, this single object will be used for - * all <em>default values</em>. If a block is specified, it will be - * called with the hash object and the key, and should return the - * default value. It is the block's responsibility to store the value - * in the hash if required. - * - * h = Hash.new("Go Fish") - * h["a"] = 100 - * h["b"] = 200 - * h["a"] #=> 100 - * h["c"] #=> "Go Fish" - * # The following alters the single default object - * h["c"].upcase! #=> "GO FISH" - * h["d"] #=> "GO FISH" - * h.keys #=> ["a", "b"] - * - * # While this creates a new default object each time - * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" } - * h["c"] #=> "Go Fish: c" - * h["c"].upcase! #=> "GO FISH: C" - * h["d"] #=> "Go Fish: d" - * h.keys #=> ["c", "d"] - * - */ - -static mrb_value -mrb_hash_init(mrb_state *mrb, mrb_value hash) -{ - mrb_value block, ifnone; - mrb_bool ifnone_p; - - ifnone = mrb_nil_value(); - mrb_get_args(mrb, "&|o?", &block, &ifnone, &ifnone_p); - mrb_hash_modify(mrb, hash); - if (!mrb_nil_p(block)) { - if (ifnone_p) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); - } - RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; - ifnone = block; - } - if (!mrb_nil_p(ifnone)) { - RHASH(hash)->flags |= MRB_HASH_DEFAULT; - mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); - } - return hash; -} - -/* 15.2.13.4.2 */ -/* - * call-seq: - * hsh[key] -> value - * - * Element Reference---Retrieves the <i>value</i> object corresponding - * to the <i>key</i> object. If not found, returns the default value (see - * <code>Hash::new</code> for details). - * - * h = { "a" => 100, "b" => 200 } - * h["a"] #=> 100 - * h["c"] #=> nil - * - */ -static mrb_value -mrb_hash_aget(mrb_state *mrb, mrb_value self) -{ - mrb_value key; - - mrb_get_args(mrb, "o", &key); - return mrb_hash_get(mrb, self, key); -} - -static mrb_value -hash_default(mrb_state *mrb, mrb_value hash, mrb_value key) -{ - if (MRB_RHASH_DEFAULT_P(hash)) { - if (MRB_RHASH_PROCDEFAULT_P(hash)) { - return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); - } - else { - return RHASH_IFNONE(hash); - } - } - return mrb_nil_value(); -} - -/* 15.2.13.4.5 */ -/* - * call-seq: - * hsh.default(key=nil) -> obj - * - * Returns the default value, the value that would be returned by - * <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>. - * See also <code>Hash::new</code> and <code>Hash#default=</code>. - * - * h = Hash.new #=> {} - * h.default #=> nil - * h.default(2) #=> nil - * - * h = Hash.new("cat") #=> {} - * h.default #=> "cat" - * h.default(2) #=> "cat" - * - * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {} - * h.default #=> nil - * h.default(2) #=> 20 - */ - -static mrb_value -mrb_hash_default(mrb_state *mrb, mrb_value hash) -{ - mrb_value key; - mrb_bool given; - - mrb_get_args(mrb, "|o?", &key, &given); - if (MRB_RHASH_DEFAULT_P(hash)) { - if (MRB_RHASH_PROCDEFAULT_P(hash)) { - if (!given) return mrb_nil_value(); - return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); - } - else { - return RHASH_IFNONE(hash); - } - } - return mrb_nil_value(); -} - -/* 15.2.13.4.6 */ -/* - * call-seq: - * hsh.default = obj -> obj - * - * Sets the default value, the value returned for a key that does not - * exist in the hash. It is not possible to set the default to a - * <code>Proc</code> that will be executed on each key lookup. - * - * h = { "a" => 100, "b" => 200 } - * h.default = "Go fish" - * h["a"] #=> 100 - * h["z"] #=> "Go fish" - * # This doesn't do what you might hope... - * h.default = proc do |hash, key| - * hash[key] = key + key - * end - * h[2] #=> #<Proc:0x401b3948@-:6> - * h["cat"] #=> #<Proc:0x401b3948@-:6> - */ - -static mrb_value -mrb_hash_set_default(mrb_state *mrb, mrb_value hash) -{ - mrb_value ifnone; - - mrb_get_args(mrb, "o", &ifnone); - mrb_hash_modify(mrb, hash); - mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); - RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT; - if (!mrb_nil_p(ifnone)) { - RHASH(hash)->flags |= MRB_HASH_DEFAULT; - } - else { - RHASH(hash)->flags &= ~MRB_HASH_DEFAULT; - } - return ifnone; -} - -/* 15.2.13.4.7 */ -/* - * call-seq: - * hsh.default_proc -> anObject - * - * If <code>Hash::new</code> was invoked with a block, return that - * block, otherwise return <code>nil</code>. - * - * h = Hash.new {|h,k| h[k] = k*k } #=> {} - * p = h.default_proc #=> #<Proc:0x401b3d08@-:1> - * a = [] #=> [] - * p.call(a, 2) - * a #=> [nil, nil, 4] - */ - - -static mrb_value -mrb_hash_default_proc(mrb_state *mrb, mrb_value hash) -{ - if (MRB_RHASH_PROCDEFAULT_P(hash)) { - return RHASH_PROCDEFAULT(hash); - } - return mrb_nil_value(); -} - -/* - * call-seq: - * hsh.default_proc = proc_obj -> proc_obj - * - * Sets the default proc to be executed on each key lookup. - * - * h.default_proc = proc do |hash, key| - * hash[key] = key + key - * end - * h[2] #=> 4 - * h["cat"] #=> "catcat" - */ - -static mrb_value -mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash) -{ - mrb_value ifnone; - - mrb_get_args(mrb, "o", &ifnone); - mrb_hash_modify(mrb, hash); - mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); - if (!mrb_nil_p(ifnone)) { - RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; - RHASH(hash)->flags |= MRB_HASH_DEFAULT; - } - else { - RHASH(hash)->flags &= ~MRB_HASH_DEFAULT; - RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT; - } - - return ifnone; -} - -MRB_API mrb_value -mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key) -{ - khash_t(ht) *h = RHASH_TBL(hash); - khiter_t k; - mrb_value delVal; - mrb_int n; - - if (h) { - k = kh_get(ht, mrb, h, key); - if (k != kh_end(h)) { - delVal = kh_value(h, k).v; - n = kh_value(h, k).n; - kh_del(ht, mrb, h, k); - for (k = kh_begin(h); k != kh_end(h); k++) { - if (!kh_exist(h, k)) continue; - if (kh_value(h, k).n > n) kh_value(h, k).n--; - } - return delVal; - } - } - - /* not found */ - return mrb_nil_value(); -} - -/* 15.2.13.4.8 */ -/* - * call-seq: - * hsh.delete(key) -> value - * hsh.delete(key) {| key | block } -> value - * - * Deletes and returns a key-value pair from <i>hsh</i> whose key is - * equal to <i>key</i>. If the key is not found, returns the - * <em>default value</em>. If the optional code block is given and the - * key is not found, pass in the key and return the result of - * <i>block</i>. - * - * h = { "a" => 100, "b" => 200 } - * h.delete("a") #=> 100 - * h.delete("z") #=> nil - * h.delete("z") { |el| "#{el} not found" } #=> "z not found" - * - */ -static mrb_value -mrb_hash_delete(mrb_state *mrb, mrb_value self) -{ - mrb_value key; - - mrb_get_args(mrb, "o", &key); - mrb_hash_modify(mrb, self); - return mrb_hash_delete_key(mrb, self, key); -} - -/* 15.2.13.4.24 */ -/* - * call-seq: - * hsh.shift -> anArray or obj - * - * Removes a key-value pair from <i>hsh</i> and returns it as the - * two-item array <code>[</code> <i>key, value</i> <code>]</code>, or - * the hash's default value if the hash is empty. - * - * h = { 1 => "a", 2 => "b", 3 => "c" } - * h.shift #=> [1, "a"] - * h #=> {2=>"b", 3=>"c"} - */ - -static mrb_value -mrb_hash_shift(mrb_state *mrb, mrb_value hash) -{ - khash_t(ht) *h = RHASH_TBL(hash); - khiter_t k; - mrb_value delKey, delVal; - - mrb_hash_modify(mrb, hash); - if (h && kh_size(h) > 0) { - for (k = kh_begin(h); k != kh_end(h); k++) { - if (!kh_exist(h, k)) continue; - - delKey = kh_key(h, k); - mrb_gc_protect(mrb, delKey); - delVal = mrb_hash_delete_key(mrb, hash, delKey); - mrb_gc_protect(mrb, delVal); - - return mrb_assoc_new(mrb, delKey, delVal); - } - } - - if (MRB_RHASH_DEFAULT_P(hash)) { - if (MRB_RHASH_PROCDEFAULT_P(hash)) { - return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value()); - } - else { - return RHASH_IFNONE(hash); - } - } - return mrb_nil_value(); -} - -/* 15.2.13.4.4 */ -/* - * call-seq: - * hsh.clear -> hsh - * - * Removes all key-value pairs from `hsh`. - * - * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200} - * h.clear #=> {} - * - */ - -MRB_API mrb_value -mrb_hash_clear(mrb_state *mrb, mrb_value hash) -{ - khash_t(ht) *h = RHASH_TBL(hash); - - mrb_hash_modify(mrb, hash); - if (h) kh_clear(ht, mrb, h); - return hash; -} - -/* 15.2.13.4.3 */ -/* 15.2.13.4.26 */ -/* - * call-seq: - * hsh[key] = value -> value - * hsh.store(key, value) -> value - * - * Element Assignment---Associates the value given by - * <i>value</i> with the key given by <i>key</i>. - * <i>key</i> should not have its value changed while it is in - * use as a key (a <code>String</code> passed as a key will be - * duplicated and frozen). - * - * h = { "a" => 100, "b" => 200 } - * h["a"] = 9 - * h["c"] = 4 - * h #=> {"a"=>9, "b"=>200, "c"=>4} - * - */ -static mrb_value -mrb_hash_aset(mrb_state *mrb, mrb_value self) -{ - mrb_value key, val; - - mrb_get_args(mrb, "oo", &key, &val); - mrb_hash_set(mrb, self, key, val); - return val; -} - -/* 15.2.13.4.20 */ -/* 15.2.13.4.25 */ -/* - * call-seq: - * hsh.length -> fixnum - * hsh.size -> fixnum - * - * Returns the number of key-value pairs in the hash. - * - * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 } - * h.length #=> 4 - * h.delete("a") #=> 200 - * h.length #=> 3 - */ -static mrb_value -mrb_hash_size_m(mrb_state *mrb, mrb_value self) -{ - khash_t(ht) *h = RHASH_TBL(self); - - if (!h) return mrb_fixnum_value(0); - return mrb_fixnum_value(kh_size(h)); -} - -/* 15.2.13.4.12 */ -/* - * call-seq: - * hsh.empty? -> true or false - * - * Returns <code>true</code> if <i>hsh</i> contains no key-value pairs. - * - * {}.empty? #=> true - * - */ -MRB_API mrb_value -mrb_hash_empty_p(mrb_state *mrb, mrb_value self) -{ - khash_t(ht) *h = RHASH_TBL(self); - - if (h) return mrb_bool_value(kh_size(h) == 0); - return mrb_true_value(); -} - -/* 15.2.13.4.29 (x)*/ -/* - * call-seq: - * hsh.to_hash => hsh - * - * Returns +self+. - */ - -static mrb_value -mrb_hash_to_hash(mrb_state *mrb, mrb_value hash) -{ - return hash; -} - -/* 15.2.13.4.19 */ -/* - * call-seq: - * hsh.keys -> array - * - * Returns a new array populated with the keys from this hash. See also - * <code>Hash#values</code>. - * - * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 } - * h.keys #=> ["a", "b", "c", "d"] - * - */ - -MRB_API mrb_value -mrb_hash_keys(mrb_state *mrb, mrb_value hash) -{ - khash_t(ht) *h = RHASH_TBL(hash); - khiter_t k; - mrb_int end; - mrb_value ary; - mrb_value *p; - - if (!h || kh_size(h) == 0) return mrb_ary_new(mrb); - ary = mrb_ary_new_capa(mrb, kh_size(h)); - end = kh_size(h)-1; - mrb_ary_set(mrb, ary, end, mrb_nil_value()); - p = RARRAY_PTR(ary); - for (k = kh_begin(h); k != kh_end(h); k++) { - if (kh_exist(h, k)) { - mrb_value kv = kh_key(h, k); - mrb_hash_value hv = kh_value(h, k); - - if (hv.n <= end) { - p[hv.n] = kv; - } - else { - p[end] = kv; - } - } - } - return ary; -} - -/* 15.2.13.4.28 */ -/* - * call-seq: - * hsh.values -> array - * - * Returns a new array populated with the values from <i>hsh</i>. See - * also <code>Hash#keys</code>. - * - * h = { "a" => 100, "b" => 200, "c" => 300 } - * h.values #=> [100, 200, 300] - * - */ - -MRB_API mrb_value -mrb_hash_values(mrb_state *mrb, mrb_value hash) -{ - khash_t(ht) *h = RHASH_TBL(hash); - khiter_t k; - mrb_value ary; - - 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)) { - mrb_hash_value hv = kh_value(h, k); - - mrb_ary_set(mrb, ary, hv.n, hv.v); - } - } - return ary; -} - -/* 15.2.13.4.13 */ -/* 15.2.13.4.15 */ -/* 15.2.13.4.18 */ -/* 15.2.13.4.21 */ -/* - * call-seq: - * hsh.has_key?(key) -> true or false - * hsh.include?(key) -> true or false - * hsh.key?(key) -> true or false - * hsh.member?(key) -> true or false - * - * Returns <code>true</code> if the given key is present in <i>hsh</i>. - * - * h = { "a" => 100, "b" => 200 } - * h.has_key?("a") #=> true - * h.has_key?("z") #=> false - * - */ - -static mrb_value -mrb_hash_has_key(mrb_state *mrb, mrb_value hash) -{ - mrb_value key; - khash_t(ht) *h; - khiter_t k; - - mrb_get_args(mrb, "o", &key); - - h = RHASH_TBL(hash); - if (h) { - k = kh_get(ht, mrb, h, key); - return mrb_bool_value(k != kh_end(h)); - } - return mrb_false_value(); -} - -/* 15.2.13.4.14 */ -/* 15.2.13.4.27 */ -/* - * call-seq: - * hsh.has_value?(value) -> true or false - * hsh.value?(value) -> true or false - * - * Returns <code>true</code> if the given value is present for some key - * in <i>hsh</i>. - * - * h = { "a" => 100, "b" => 200 } - * h.has_value?(100) #=> true - * h.has_value?(999) #=> false - */ - -static mrb_value -mrb_hash_has_value(mrb_state *mrb, mrb_value hash) -{ - mrb_value val; - khash_t(ht) *h; - khiter_t k; - - mrb_get_args(mrb, "o", &val); - h = RHASH_TBL(hash); - - if (h) { - for (k = kh_begin(h); k != kh_end(h); k++) { - if (!kh_exist(h, k)) continue; - - if (mrb_equal(mrb, kh_value(h, k).v, val)) { - return mrb_true_value(); - } - } - } - return mrb_false_value(); -} - -void -mrb_init_hash(mrb_state *mrb) -{ - struct RClass *h; - - mrb->hash_class = h = mrb_define_class(mrb, "Hash", mrb->object_class); /* 15.2.13 */ - MRB_SET_INSTANCE_TT(h, MRB_TT_HASH); - - mrb_define_method(mrb, h, "[]", mrb_hash_aget, MRB_ARGS_REQ(1)); /* 15.2.13.4.2 */ - mrb_define_method(mrb, h, "[]=", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.3 */ - mrb_define_method(mrb, h, "clear", mrb_hash_clear, MRB_ARGS_NONE()); /* 15.2.13.4.4 */ - mrb_define_method(mrb, h, "default", mrb_hash_default, MRB_ARGS_ANY()); /* 15.2.13.4.5 */ - mrb_define_method(mrb, h, "default=", mrb_hash_set_default, MRB_ARGS_REQ(1)); /* 15.2.13.4.6 */ - mrb_define_method(mrb, h, "default_proc", mrb_hash_default_proc,MRB_ARGS_NONE()); /* 15.2.13.4.7 */ - mrb_define_method(mrb, h, "default_proc=", mrb_hash_set_default_proc,MRB_ARGS_REQ(1)); /* 15.2.13.4.7 */ - mrb_define_method(mrb, h, "__delete", mrb_hash_delete, MRB_ARGS_REQ(1)); /* core of 15.2.13.4.8 */ - mrb_define_method(mrb, h, "empty?", mrb_hash_empty_p, MRB_ARGS_NONE()); /* 15.2.13.4.12 */ - mrb_define_method(mrb, h, "has_key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.13 */ - mrb_define_method(mrb, h, "has_value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */ - mrb_define_method(mrb, h, "include?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */ - mrb_define_method(mrb, h, "initialize", mrb_hash_init, MRB_ARGS_OPT(1)); /* 15.2.13.4.16 */ - mrb_define_method(mrb, h, "key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */ - mrb_define_method(mrb, h, "keys", mrb_hash_keys, MRB_ARGS_NONE()); /* 15.2.13.4.19 */ - mrb_define_method(mrb, h, "length", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.20 */ - mrb_define_method(mrb, h, "member?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.21 */ - mrb_define_method(mrb, h, "shift", mrb_hash_shift, MRB_ARGS_NONE()); /* 15.2.13.4.24 */ - mrb_define_method(mrb, h, "dup", mrb_hash_dup, MRB_ARGS_NONE()); - mrb_define_method(mrb, h, "size", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.25 */ - mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */ - mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */ - mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */ - - mrb_define_method(mrb, h, "to_hash", mrb_hash_to_hash, MRB_ARGS_NONE()); /* 15.2.13.4.29 (x)*/ -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/init.c b/web/server/h2o/libh2o/deps/mruby/src/init.c deleted file mode 100644 index afd69975a..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/init.c +++ /dev/null @@ -1,51 +0,0 @@ -/* -** init.c - initialize mruby core -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> - -void mrb_init_symtbl(mrb_state*); -void mrb_init_class(mrb_state*); -void mrb_init_object(mrb_state*); -void mrb_init_kernel(mrb_state*); -void mrb_init_comparable(mrb_state*); -void mrb_init_enumerable(mrb_state*); -void mrb_init_symbol(mrb_state*); -void mrb_init_string(mrb_state*); -void mrb_init_exception(mrb_state*); -void mrb_init_proc(mrb_state*); -void mrb_init_array(mrb_state*); -void mrb_init_hash(mrb_state*); -void mrb_init_numeric(mrb_state*); -void mrb_init_range(mrb_state*); -void mrb_init_gc(mrb_state*); -void mrb_init_math(mrb_state*); -void mrb_init_version(mrb_state*); -void mrb_init_mrblib(mrb_state*); - -#define DONE mrb_gc_arena_restore(mrb, 0); -void -mrb_init_core(mrb_state *mrb) -{ - mrb_init_symtbl(mrb); DONE; - - mrb_init_class(mrb); DONE; - mrb_init_object(mrb); DONE; - mrb_init_kernel(mrb); DONE; - mrb_init_comparable(mrb); DONE; - mrb_init_enumerable(mrb); DONE; - - mrb_init_symbol(mrb); DONE; - mrb_init_string(mrb); DONE; - mrb_init_exception(mrb); DONE; - mrb_init_proc(mrb); DONE; - mrb_init_array(mrb); DONE; - mrb_init_hash(mrb); DONE; - mrb_init_numeric(mrb); DONE; - mrb_init_range(mrb); DONE; - mrb_init_gc(mrb); DONE; - mrb_init_version(mrb); DONE; - mrb_init_mrblib(mrb); DONE; -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/kernel.c b/web/server/h2o/libh2o/deps/mruby/src/kernel.c deleted file mode 100644 index 4e95ab24b..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/kernel.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* -** kernel.c - Kernel module -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/hash.h> -#include <mruby/class.h> -#include <mruby/proc.h> -#include <mruby/string.h> -#include <mruby/variable.h> -#include <mruby/error.h> -#include <mruby/istruct.h> - -typedef enum { - NOEX_PUBLIC = 0x00, - NOEX_NOSUPER = 0x01, - NOEX_PRIVATE = 0x02, - NOEX_PROTECTED = 0x04, - NOEX_MASK = 0x06, - NOEX_BASIC = 0x08, - NOEX_UNDEF = NOEX_NOSUPER, - NOEX_MODFUNC = 0x12, - NOEX_SUPER = 0x20, - NOEX_VCALL = 0x40, - NOEX_RESPONDS = 0x80 -} mrb_method_flag_t; - -MRB_API mrb_bool -mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func) -{ - struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid); - if (MRB_PROC_CFUNC_P(me) && (me->body.func == func)) - return TRUE; - return FALSE; -} - -static mrb_bool -mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj) -{ - return mrb_func_basic_p(mrb, obj, mrb_intern_lit(mrb, "to_s"), mrb_any_to_s); -} - -/* 15.3.1.3.17 */ -/* - * call-seq: - * obj.inspect -> string - * - * Returns a string containing a human-readable representation of - * <i>obj</i>. If not overridden and no instance variables, uses the - * <code>to_s</code> method to generate the string. - * <i>obj</i>. If not overridden, uses the <code>to_s</code> method to - * generate the string. - * - * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]" - * Time.new.inspect #=> "2008-03-08 19:43:39 +0900" - */ -MRB_API mrb_value -mrb_obj_inspect(mrb_state *mrb, mrb_value obj) -{ - if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) { - return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); - } - return mrb_any_to_s(mrb, obj); -} - -/* 15.3.1.3.2 */ -/* - * call-seq: - * obj === other -> true or false - * - * Case Equality---For class <code>Object</code>, effectively the same - * as calling <code>#==</code>, but typically overridden by descendants - * to provide meaningful semantics in <code>case</code> statements. - */ -static mrb_value -mrb_equal_m(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "o", &arg); - return mrb_bool_value(mrb_equal(mrb, self, arg)); -} - -/* 15.3.1.3.3 */ -/* 15.3.1.3.33 */ -/* - * Document-method: __id__ - * Document-method: object_id - * - * call-seq: - * obj.__id__ -> fixnum - * obj.object_id -> fixnum - * - * Returns an integer identifier for <i>obj</i>. The same number will - * be returned on all calls to <code>id</code> for a given object, and - * no two active objects will share an id. - * <code>Object#object_id</code> is a different concept from the - * <code>:name</code> notation, which returns the symbol id of - * <code>name</code>. Replaces the deprecated <code>Object#id</code>. - */ -mrb_value -mrb_obj_id_m(mrb_state *mrb, mrb_value self) -{ - return mrb_fixnum_value(mrb_obj_id(self)); -} - -/* 15.3.1.2.2 */ -/* 15.3.1.2.5 */ -/* 15.3.1.3.6 */ -/* 15.3.1.3.25 */ -/* - * call-seq: - * block_given? -> true or false - * iterator? -> true or false - * - * Returns <code>true</code> if <code>yield</code> would execute a - * block in the current context. The <code>iterator?</code> form - * is mildly deprecated. - * - * def try - * if block_given? - * yield - * else - * "no block" - * end - * end - * try #=> "no block" - * try { "hello" } #=> "hello" - * try do "hello" end #=> "hello" - */ -static mrb_value -mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) -{ - mrb_callinfo *ci = mrb->c->ci; - mrb_value *bp; - - bp = ci->stackent + 1; - ci--; - if (ci <= mrb->c->cibase) { - return mrb_false_value(); - } - /* block_given? called within block; check upper scope */ - if (ci->proc->env) { - struct REnv *e = ci->proc->env; - - while (e->c) { - e = (struct REnv*)e->c; - } - /* top-level does not have block slot (always false) */ - if (e->stack == mrb->c->stbase) - return mrb_false_value(); - if (e->stack && e->cioff < 0) { - /* use saved block arg position */ - bp = &e->stack[-e->cioff]; - ci = 0; /* no callinfo available */ - } - else { - ci = e->cxt.c->cibase + e->cioff; - bp = ci[1].stackent + 1; - } - } - if (ci && ci->argc > 0) { - bp += ci->argc; - } - if (mrb_nil_p(*bp)) - return mrb_false_value(); - return mrb_true_value(); -} - -/* 15.3.1.3.7 */ -/* - * call-seq: - * obj.class -> class - * - * Returns the class of <i>obj</i>. This method must always be - * called with an explicit receiver, as <code>class</code> is also a - * reserved word in Ruby. - * - * 1.class #=> Fixnum - * self.class #=> Object - */ -static mrb_value -mrb_obj_class_m(mrb_state *mrb, mrb_value self) -{ - return mrb_obj_value(mrb_obj_class(mrb, self)); -} - -static struct RClass* -mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj) -{ - struct RClass *klass = mrb_basic_ptr(obj)->c; - - if (klass->tt != MRB_TT_SCLASS) - return klass; - else { - /* copy singleton(unnamed) class */ - struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class); - - switch (mrb_type(obj)) { - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - break; - default: - clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass)); - break; - } - clone->super = klass->super; - if (klass->iv) { - mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass)); - mrb_obj_iv_set(mrb, (struct RObject*)clone, mrb_intern_lit(mrb, "__attached__"), obj); - } - if (klass->mt) { - clone->mt = kh_copy(mt, mrb, klass->mt); - } - else { - clone->mt = kh_init(mt, mrb); - } - clone->tt = MRB_TT_SCLASS; - return clone; - } -} - -static void -copy_class(mrb_state *mrb, mrb_value dst, mrb_value src) -{ - struct RClass *dc = mrb_class_ptr(dst); - struct RClass *sc = mrb_class_ptr(src); - /* if the origin is not the same as the class, then the origin and - the current class need to be copied */ - if (sc->flags & MRB_FLAG_IS_PREPENDED) { - struct RClass *c0 = sc->super; - struct RClass *c1 = dc; - - /* copy prepended iclasses */ - while (!(c0->flags & MRB_FLAG_IS_ORIGIN)) { - c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); - c1 = c1->super; - c0 = c0->super; - } - c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); - c1->super->flags |= MRB_FLAG_IS_ORIGIN; - } - if (sc->mt) { - dc->mt = kh_copy(mt, mrb, sc->mt); - } - else { - dc->mt = kh_init(mt, mrb); - } - dc->super = sc->super; - MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); -} - -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: - case MRB_TT_EXCEPTION: - mrb_iv_copy(mrb, dest, obj); - break; - case MRB_TT_ISTRUCT: - mrb_istruct_copy(dest, obj); - break; - - default: - break; - } - mrb_funcall(mrb, dest, "initialize_copy", 1, obj); -} - -/* 15.3.1.3.8 */ -/* - * call-seq: - * obj.clone -> an_object - * - * Produces a shallow copy of <i>obj</i>---the instance variables of - * <i>obj</i> are copied, but not the objects they reference. Copies - * the frozen state of <i>obj</i>. See also the discussion - * under <code>Object#dup</code>. - * - * class Klass - * attr_accessor :str - * end - * s1 = Klass.new #=> #<Klass:0x401b3a38> - * s1.str = "Hello" #=> "Hello" - * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> - * s2.str[1,4] = "i" #=> "i" - * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" - * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - * - * Some Class(True False Nil Symbol Fixnum Float) Object cannot clone. - */ -MRB_API mrb_value -mrb_obj_clone(mrb_state *mrb, mrb_value self) -{ - struct RObject *p; - mrb_value clone; - - if (mrb_immediate_p(self)) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self); - } - if (mrb_type(self) == MRB_TT_SCLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); - } - p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); - p->c = mrb_singleton_class_clone(mrb, self); - mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c); - clone = mrb_obj_value(p); - init_copy(mrb, clone, self); - - return clone; -} - -/* 15.3.1.3.9 */ -/* - * call-seq: - * obj.dup -> an_object - * - * Produces a shallow copy of <i>obj</i>---the instance variables of - * <i>obj</i> are copied, but not the objects they reference. - * <code>dup</code> copies the frozen state of <i>obj</i>. See also - * the discussion under <code>Object#clone</code>. In general, - * <code>clone</code> and <code>dup</code> may have different semantics - * in descendant classes. While <code>clone</code> is used to duplicate - * an object, including its internal state, <code>dup</code> typically - * uses the class of the descendant object to create the new instance. - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - */ - -MRB_API mrb_value -mrb_obj_dup(mrb_state *mrb, mrb_value obj) -{ - struct RBasic *p; - mrb_value dup; - - if (mrb_immediate_p(obj)) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj); - } - if (mrb_type(obj) == MRB_TT_SCLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class"); - } - 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; -} - -static mrb_value -mrb_obj_extend(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value obj) -{ - mrb_int i; - - if (argc == 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)"); - } - for (i = 0; i < argc; i++) { - mrb_check_type(mrb, argv[i], MRB_TT_MODULE); - } - while (argc--) { - mrb_funcall(mrb, argv[argc], "extend_object", 1, obj); - mrb_funcall(mrb, argv[argc], "extended", 1, obj); - } - return obj; -} - -/* 15.3.1.3.13 */ -/* - * call-seq: - * obj.extend(module, ...) -> obj - * - * Adds to _obj_ the instance methods from each module given as a - * parameter. - * - * module Mod - * def hello - * "Hello from Mod.\n" - * end - * end - * - * class Klass - * def hello - * "Hello from Klass.\n" - * end - * end - * - * k = Klass.new - * k.hello #=> "Hello from Klass.\n" - * k.extend(Mod) #=> #<Klass:0x401b3bc8> - * k.hello #=> "Hello from Mod.\n" - */ -static mrb_value -mrb_obj_extend_m(mrb_state *mrb, mrb_value self) -{ - mrb_value *argv; - mrb_int argc; - - mrb_get_args(mrb, "*", &argv, &argc); - return mrb_obj_extend(mrb, argc, argv, self); -} - -static mrb_value -mrb_obj_freeze(mrb_state *mrb, mrb_value self) -{ - struct RBasic *b; - - switch (mrb_type(self)) { - case MRB_TT_FALSE: - case MRB_TT_TRUE: - case MRB_TT_FIXNUM: - case MRB_TT_SYMBOL: - case MRB_TT_FLOAT: - return self; - default: - break; - } - - b = mrb_basic_ptr(self); - if (!MRB_FROZEN_P(b)) { - MRB_SET_FROZEN_FLAG(b); - } - return self; -} - -static mrb_value -mrb_obj_frozen(mrb_state *mrb, mrb_value self) -{ - struct RBasic *b; - - switch (mrb_type(self)) { - case MRB_TT_FALSE: - case MRB_TT_TRUE: - case MRB_TT_FIXNUM: - case MRB_TT_SYMBOL: - case MRB_TT_FLOAT: - return mrb_true_value(); - default: - break; - } - - b = mrb_basic_ptr(self); - if (!MRB_FROZEN_P(b)) { - return mrb_false_value(); - } - return mrb_true_value(); -} - -/* 15.3.1.3.15 */ -/* - * call-seq: - * obj.hash -> fixnum - * - * Generates a <code>Fixnum</code> hash value for this object. This - * function must have the property that <code>a.eql?(b)</code> implies - * <code>a.hash == b.hash</code>. The hash value is used by class - * <code>Hash</code>. Any hash value that exceeds the capacity of a - * <code>Fixnum</code> will be truncated before being used. - */ -MRB_API mrb_value -mrb_obj_hash(mrb_state *mrb, mrb_value self) -{ - return mrb_fixnum_value(mrb_obj_id(self)); -} - -/* 15.3.1.3.16 */ -static mrb_value -mrb_obj_init_copy(mrb_state *mrb, mrb_value self) -{ - mrb_value orig; - - mrb_get_args(mrb, "o", &orig); - if (mrb_obj_equal(mrb, self, orig)) return self; - if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) { - mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object"); - } - return self; -} - - -MRB_API mrb_bool -mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c) -{ - if (mrb_obj_class(mrb, obj) == c) return TRUE; - return FALSE; -} - -/* 15.3.1.3.19 */ -/* - * call-seq: - * obj.instance_of?(class) -> true or false - * - * Returns <code>true</code> if <i>obj</i> is an instance of the given - * class. See also <code>Object#kind_of?</code>. - */ -static mrb_value -obj_is_instance_of(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "C", &arg); - - return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg))); -} - -/* 15.3.1.3.20 */ -/* - * call-seq: - * obj.instance_variable_defined?(symbol) -> true or false - * - * Returns <code>true</code> if the given instance variable is - * defined in <i>obj</i>. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_defined?(:@a) #=> true - * fred.instance_variable_defined?("@b") #=> true - * fred.instance_variable_defined?("@c") #=> false - */ -static mrb_value -mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) -{ - mrb_sym sym; - - mrb_get_args(mrb, "n", &sym); - mrb_iv_check(mrb, sym); - return mrb_bool_value(mrb_iv_defined(mrb, self, sym)); -} - -/* 15.3.1.3.21 */ -/* - * call-seq: - * obj.instance_variable_get(symbol) -> obj - * - * Returns the value of the given instance variable, or nil if the - * instance variable is not set. The <code>@</code> part of the - * variable name should be included for regular instance - * variables. Throws a <code>NameError</code> exception if the - * supplied symbol is not valid as an instance variable name. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_get(:@a) #=> "cat" - * fred.instance_variable_get("@b") #=> 99 - */ -static mrb_value -mrb_obj_ivar_get(mrb_state *mrb, mrb_value self) -{ - mrb_sym iv_name; - - mrb_get_args(mrb, "n", &iv_name); - mrb_iv_check(mrb, iv_name); - return mrb_iv_get(mrb, self, iv_name); -} - -/* 15.3.1.3.22 */ -/* - * call-seq: - * obj.instance_variable_set(symbol, obj) -> obj - * - * Sets the instance variable names by <i>symbol</i> to - * <i>object</i>, thereby frustrating the efforts of the class's - * author to attempt to provide proper encapsulation. The variable - * did not have to exist prior to this call. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_set(:@a, 'dog') #=> "dog" - * fred.instance_variable_set(:@c, 'cat') #=> "cat" - * fred.inspect #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">" - */ -static mrb_value -mrb_obj_ivar_set(mrb_state *mrb, mrb_value self) -{ - mrb_sym iv_name; - mrb_value val; - - mrb_get_args(mrb, "no", &iv_name, &val); - mrb_iv_check(mrb, iv_name); - mrb_iv_set(mrb, self, iv_name, val); - return val; -} - -/* 15.3.1.3.24 */ -/* 15.3.1.3.26 */ -/* - * call-seq: - * obj.is_a?(class) -> true or false - * obj.kind_of?(class) -> true or false - * - * Returns <code>true</code> if <i>class</i> is the class of - * <i>obj</i>, or if <i>class</i> is one of the superclasses of - * <i>obj</i> or modules included in <i>obj</i>. - * - * module M; end - * class A - * include M - * end - * class B < A; end - * class C < B; end - * b = B.new - * b.instance_of? A #=> false - * b.instance_of? B #=> true - * b.instance_of? C #=> false - * b.instance_of? M #=> false - * b.kind_of? A #=> true - * b.kind_of? B #=> true - * b.kind_of? C #=> false - * b.kind_of? M #=> true - */ -static mrb_value -mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "C", &arg); - - return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg))); -} - -KHASH_DECLARE(st, mrb_sym, char, FALSE) -KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal) - -static void -method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) -{ - khint_t i; - - khash_t(mt) *h = klass->mt; - if (!h) return; - for (i=0;i<kh_end(h);i++) { - if (kh_exist(h, i) && kh_value(h, i)) { - kh_put(st, mrb, set, kh_key(h, i)); - } - } -} - -mrb_value -mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj) -{ - khint_t i; - mrb_value ary; - mrb_bool prepended = FALSE; - struct RClass* oldklass; - khash_t(st)* set = kh_init(st, mrb); - - if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) { - MRB_CLASS_ORIGIN(klass); - prepended = TRUE; - } - - oldklass = 0; - while (klass && (klass != oldklass)) { - method_entry_loop(mrb, klass, set); - if ((klass->tt == MRB_TT_ICLASS && !prepended) || - (klass->tt == MRB_TT_SCLASS)) { - } - else { - if (!recur) break; - } - oldklass = klass; - klass = klass->super; - } - - ary = mrb_ary_new(mrb); - for (i=0;i<kh_end(set);i++) { - if (kh_exist(set, i)) { - mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i))); - } - } - kh_destroy(st, mrb, set); - - return ary; -} - -static mrb_value -mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) -{ - khint_t i; - mrb_value ary; - struct RClass* klass; - khash_t(st)* set = kh_init(st, mrb); - - klass = mrb_class(mrb, obj); - - if (klass && (klass->tt == MRB_TT_SCLASS)) { - method_entry_loop(mrb, klass, set); - klass = klass->super; - } - if (recur) { - while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) { - method_entry_loop(mrb, klass, set); - klass = klass->super; - } - } - - ary = mrb_ary_new(mrb); - for (i=0;i<kh_end(set);i++) { - if (kh_exist(set, i)) { - mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i))); - } - } - kh_destroy(st, mrb, set); - - return ary; -} - -static mrb_value -mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag) -{ - return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0); -} -/* 15.3.1.3.31 */ -/* - * call-seq: - * obj.methods -> array - * - * Returns a list of the names of methods publicly accessible in - * <i>obj</i>. This will include all the methods accessible in - * <i>obj</i>'s ancestors. - * - * class Klass - * def kMethod() - * end - * end - * k = Klass.new - * k.methods[0..9] #=> [:kMethod, :respond_to?, :nil?, :is_a?, - * # :class, :instance_variable_set, - * # :methods, :extend, :__send__, :instance_eval] - * k.methods.length #=> 42 - */ -static mrb_value -mrb_obj_methods_m(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, (mrb_method_flag_t)0); /* everything but private */ -} - -/* 15.3.1.3.32 */ -/* - * call_seq: - * nil.nil? -> true - * <anything_else>.nil? -> false - * - * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>. - */ -static mrb_value -mrb_false(mrb_state *mrb, mrb_value self) -{ - return mrb_false_value(); -} - -/* 15.3.1.3.36 */ -/* - * call-seq: - * obj.private_methods(all=true) -> array - * - * Returns the list of private methods accessible to <i>obj</i>. If - * the <i>all</i> parameter is set to <code>false</code>, only those methods - * in the receiver will be listed. - */ -static mrb_value -mrb_obj_private_methods(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, NOEX_PRIVATE); /* private attribute not define */ -} - -/* 15.3.1.3.37 */ -/* - * call-seq: - * obj.protected_methods(all=true) -> array - * - * Returns the list of protected methods accessible to <i>obj</i>. If - * the <i>all</i> parameter is set to <code>false</code>, only those methods - * in the receiver will be listed. - */ -static mrb_value -mrb_obj_protected_methods(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, NOEX_PROTECTED); /* protected attribute not define */ -} - -/* 15.3.1.3.38 */ -/* - * call-seq: - * obj.public_methods(all=true) -> array - * - * Returns the list of public methods accessible to <i>obj</i>. If - * the <i>all</i> parameter is set to <code>false</code>, only those methods - * in the receiver will be listed. - */ -static mrb_value -mrb_obj_public_methods(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, NOEX_PUBLIC); /* public attribute not define */ -} - -/* 15.3.1.2.12 */ -/* 15.3.1.3.40 */ -/* - * call-seq: - * raise - * raise(string) - * raise(exception [, string]) - * - * With no arguments, raises a <code>RuntimeError</code> - * With a single +String+ argument, raises a - * +RuntimeError+ with the string as a message. Otherwise, - * the first parameter should be the name of an +Exception+ - * class (or an object that returns an +Exception+ object when sent - * an +exception+ message). The optional second parameter sets the - * message associated with the exception, and the third parameter is an - * array of callback information. Exceptions are caught by the - * +rescue+ clause of <code>begin...end</code> blocks. - * - * raise "Failed to create socket" - * raise ArgumentError, "No parameters", caller - */ -MRB_API mrb_value -mrb_f_raise(mrb_state *mrb, mrb_value self) -{ - mrb_value a[2], exc; - int argc; - - - argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); - switch (argc) { - case 0: - mrb_raise(mrb, E_RUNTIME_ERROR, ""); - break; - case 1: - if (mrb_string_p(a[0])) { - a[1] = a[0]; - argc = 2; - a[0] = mrb_obj_value(E_RUNTIME_ERROR); - } - /* fall through */ - default: - exc = mrb_make_exception(mrb, argc, a); - mrb_exc_raise(mrb, exc); - break; - } - return mrb_nil_value(); /* not reached */ -} - -/* 15.3.1.3.41 */ -/* - * call-seq: - * obj.remove_instance_variable(symbol) -> obj - * - * Removes the named instance variable from <i>obj</i>, returning that - * variable's value. - * - * class Dummy - * attr_reader :var - * def initialize - * @var = 99 - * end - * def remove - * remove_instance_variable(:@var) - * end - * end - * d = Dummy.new - * d.var #=> 99 - * d.remove #=> 99 - * d.var #=> nil - */ -static mrb_value -mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) -{ - mrb_sym sym; - mrb_value val; - - mrb_get_args(mrb, "n", &sym); - mrb_iv_check(mrb, sym); - val = mrb_iv_remove(mrb, self, sym); - if (mrb_undef_p(val)) { - mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym)); - } - return val; -} - -void -mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) -{ - mrb_sym inspect; - mrb_value repr; - - inspect = mrb_intern_lit(mrb, "inspect"); - if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { - /* method missing in inspect; avoid recursion */ - repr = mrb_any_to_s(mrb, self); - } - else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) { - repr = mrb_funcall_argv(mrb, self, inspect, 0, 0); - if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) { - repr = mrb_any_to_s(mrb, self); - } - } - else { - repr = mrb_any_to_s(mrb, self); - } - - mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S", - mrb_sym2str(mrb, name), repr); -} - -/* 15.3.1.3.30 */ -/* - * call-seq: - * obj.method_missing(symbol [, *args] ) -> result - * - * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle. - * <i>symbol</i> is the symbol for the method called, and <i>args</i> - * are any arguments that were passed to it. By default, the interpreter - * raises an error when this method is called. However, it is possible - * to override the method to provide more dynamic behavior. - * If it is decided that a particular method should not be handled, then - * <i>super</i> should be called, so that ancestors can pick up the - * missing method. - * The example below creates - * a class <code>Roman</code>, which responds to methods with names - * consisting of roman numerals, returning the corresponding integer - * values. - * - * class Roman - * def romanToInt(str) - * # ... - * end - * def method_missing(methId) - * str = methId.id2name - * romanToInt(str) - * end - * end - * - * r = Roman.new - * r.iv #=> 4 - * r.xxiii #=> 23 - * r.mm #=> 2000 - */ -#ifdef MRB_DEFAULT_METHOD_MISSING -static mrb_value -mrb_obj_missing(mrb_state *mrb, mrb_value mod) -{ - mrb_sym name; - mrb_value *a; - mrb_int alen; - - mrb_get_args(mrb, "n*!", &name, &a, &alen); - mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a)); - /* not reached */ - return mrb_nil_value(); -} -#endif - -static inline mrb_bool -basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) -{ - return mrb_respond_to(mrb, obj, id); -} -/* 15.3.1.3.43 */ -/* - * call-seq: - * obj.respond_to?(symbol, include_private=false) -> true or false - * - * Returns +true+ if _obj_ responds to the given - * method. Private methods are included in the search only if the - * optional second parameter evaluates to +true+. - * - * If the method is not implemented, - * as Process.fork on Windows, File.lchmod on GNU/Linux, etc., - * false is returned. - * - * If the method is not defined, <code>respond_to_missing?</code> - * method is called and the result is returned. - */ -static mrb_value -obj_respond_to(mrb_state *mrb, mrb_value self) -{ - mrb_value mid; - mrb_sym id, rtm_id; - mrb_bool priv = FALSE, respond_to_p = TRUE; - - mrb_get_args(mrb, "o|b", &mid, &priv); - - if (mrb_symbol_p(mid)) { - id = mrb_symbol(mid); - } - else { - mrb_value tmp; - if (mrb_string_p(mid)) { - tmp = mrb_check_intern_str(mrb, mid); - } - else { - tmp = mrb_check_string_type(mrb, mid); - if (mrb_nil_p(tmp)) { - tmp = mrb_inspect(mrb, mid); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp); - } - tmp = mrb_check_intern_str(mrb, tmp); - } - if (mrb_nil_p(tmp)) { - respond_to_p = FALSE; - } - else { - id = mrb_symbol(tmp); - } - } - - if (respond_to_p) { - 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, !priv)) { - mrb_value args[2], v; - args[0] = mid; - args[1] = mrb_bool_value(priv); - v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); - return mrb_bool_value(mrb_bool(v)); - } - } - return mrb_bool_value(respond_to_p); -} - -/* 15.3.1.3.45 */ -/* - * call-seq: - * obj.singleton_methods(all=true) -> array - * - * Returns an array of the names of singleton methods for <i>obj</i>. - * If the optional <i>all</i> parameter is true, the list will include - * methods in modules included in <i>obj</i>. - * Only public and protected singleton methods are returned. - * - * module Other - * def three() end - * end - * - * class Single - * def Single.four() end - * end - * - * a = Single.new - * - * def a.one() - * end - * - * class << a - * include Other - * def two() - * end - * end - * - * Single.singleton_methods #=> [:four] - * a.singleton_methods(false) #=> [:two, :one] - * a.singleton_methods #=> [:two, :one, :three] - */ -static mrb_value -mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_singleton_methods(mrb, recur, self); -} - -static mrb_value -mod_define_singleton_method(mrb_state *mrb, mrb_value self) -{ - struct RProc *p; - mrb_sym mid; - mrb_value blk = mrb_nil_value(); - - mrb_get_args(mrb, "n&", &mid, &blk); - if (mrb_nil_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); - mrb_proc_copy(p, mrb_proc_ptr(blk)); - p->flags |= MRB_PROC_STRICT; - mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p); - return mrb_symbol_value(mid); -} - -static mrb_value -mrb_obj_ceqq(mrb_state *mrb, mrb_value self) -{ - mrb_value v; - mrb_int i, len; - mrb_sym eqq = mrb_intern_lit(mrb, "==="); - mrb_value ary = mrb_ary_splat(mrb, self); - - mrb_get_args(mrb, "o", &v); - len = RARRAY_LEN(ary); - for (i=0; i<len; i++) { - mrb_value c = mrb_funcall_argv(mrb, mrb_ary_entry(ary, i), eqq, 1, &v); - if (mrb_test(c)) return mrb_true_value(); - } - return mrb_false_value(); -} - -/* 15.3.1.2.7 */ -/* - * call-seq: - * local_variables -> array - * - * Returns the names of local variables in the current scope. - * - * [mruby limitation] - * If variable symbol information was stripped out from - * compiled binary files using `mruby-strip -l`, this - * method always returns an empty array. - */ -static mrb_value -mrb_local_variables(mrb_state *mrb, mrb_value self) -{ - struct RProc *proc; - mrb_irep *irep; - mrb_value vars; - size_t i; - - proc = mrb->c->ci[-1].proc; - - if (MRB_PROC_CFUNC_P(proc)) { - return mrb_ary_new(mrb); - } - vars = mrb_hash_new(mrb); - irep = proc->body.irep; - while (irep) { - if (!irep->lv) break; - for (i = 0; i + 1 < irep->nlocals; ++i) { - if (irep->lv[i].name) { - mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value()); - } - } - if (!proc->env) break; - irep = irep->outer; - } - - return mrb_hash_keys(mrb, vars); -} - -mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); -void -mrb_init_kernel(mrb_state *mrb) -{ - struct RClass *krn; - - mrb->kernel_module = krn = mrb_define_module(mrb, "Kernel"); /* 15.3.1 */ - mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.2 */ - mrb_define_class_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.2.4 */ - mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.5 */ - mrb_define_class_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.2.7 */ -; /* 15.3.1.2.11 */ - mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_OPT(2)); /* 15.3.1.2.12 */ - - mrb_define_method(mrb, krn, "singleton_class", mrb_singleton_class, MRB_ARGS_NONE()); - - mrb_define_method(mrb, krn, "===", mrb_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */ - 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 */ - mrb_define_method(mrb, krn, "dup", mrb_obj_dup, MRB_ARGS_NONE()); /* 15.3.1.3.9 */ - mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */ - mrb_define_method(mrb, krn, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */ - mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, MRB_ARGS_ANY()); /* 15.3.1.3.13 */ - mrb_define_method(mrb, krn, "freeze", mrb_obj_freeze, MRB_ARGS_NONE()); - mrb_define_method(mrb, krn, "frozen?", mrb_obj_frozen, MRB_ARGS_NONE()); - mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.3.14 */ - mrb_define_method(mrb, krn, "hash", mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */ - mrb_define_method(mrb, krn, "initialize_copy", mrb_obj_init_copy, MRB_ARGS_REQ(1)); /* 15.3.1.3.16 */ - mrb_define_method(mrb, krn, "inspect", mrb_obj_inspect, MRB_ARGS_NONE()); /* 15.3.1.3.17 */ - mrb_define_method(mrb, krn, "instance_of?", obj_is_instance_of, MRB_ARGS_REQ(1)); /* 15.3.1.3.19 */ - mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined, MRB_ARGS_REQ(1)); /* 15.3.1.3.20 */ - mrb_define_method(mrb, krn, "instance_variable_get", mrb_obj_ivar_get, MRB_ARGS_REQ(1)); /* 15.3.1.3.21 */ - mrb_define_method(mrb, krn, "instance_variable_set", mrb_obj_ivar_set, MRB_ARGS_REQ(2)); /* 15.3.1.3.22 */ - mrb_define_method(mrb, krn, "instance_variables", mrb_obj_instance_variables, MRB_ARGS_NONE()); /* 15.3.1.3.23 */ - mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.24 */ - mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.25 */ - mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.26 */ - mrb_define_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.3.28 */ -#ifdef MRB_DEFAULT_METHOD_MISSING - mrb_define_method(mrb, krn, "method_missing", mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */ -#endif - mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.31 */ - mrb_define_method(mrb, krn, "nil?", mrb_false, MRB_ARGS_NONE()); /* 15.3.1.3.32 */ - mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.33 */ - mrb_define_method(mrb, krn, "private_methods", mrb_obj_private_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.36 */ - mrb_define_method(mrb, krn, "protected_methods", mrb_obj_protected_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.37 */ - mrb_define_method(mrb, krn, "public_methods", mrb_obj_public_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.38 */ - mrb_define_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_ANY()); /* 15.3.1.3.40 */ - mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1)); /* 15.3.1.3.41 */ - mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ANY()); /* 15.3.1.3.43 */ - mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.44 */ - mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.45 */ - mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_ANY()); - mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ - mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ - - mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); - mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone")); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/load.c b/web/server/h2o/libh2o/deps/mruby/src/load.c deleted file mode 100644 index 8ae607ffa..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/load.c +++ /dev/null @@ -1,704 +0,0 @@ -/* -** load.c - mruby binary loader -** -** See Copyright Notice in mruby.h -*/ - -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <mruby/dump.h> -#include <mruby/irep.h> -#include <mruby/proc.h> -#include <mruby/string.h> -#include <mruby/debug.h> -#include <mruby/error.h> - -#if SIZE_MAX < UINT32_MAX -# 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 - -#define SIZE_ERROR_MUL(nmemb, size) ((size_t)(nmemb) > SIZE_MAX / (size)) - -static size_t -skip_padding(const uint8_t *buf) -{ - const size_t align = MRB_DUMP_ALIGNMENT; - return -(intptr_t)buf & (align-1); -} - -static size_t -offset_crc_body(void) -{ - struct rite_binary_header header; - return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc); -} - -static mrb_irep* -read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) -{ - int i; - const uint8_t *src = bin; - ptrdiff_t diff; - uint16_t tt, pool_data_len, snl; - int plen; - int ai = mrb_gc_arena_save(mrb); - mrb_irep *irep = mrb_add_irep(mrb); - - /* skip record size */ - src += sizeof(uint32_t); - - /* number of local variable */ - irep->nlocals = bin_to_uint16(src); - src += sizeof(uint16_t); - - /* number of register variable */ - irep->nregs = bin_to_uint16(src); - src += sizeof(uint16_t); - - /* number of child irep */ - irep->rlen = (size_t)bin_to_uint16(src); - src += sizeof(uint16_t); - - /* Binary Data Section */ - /* ISEQ BLOCK */ - irep->ilen = (size_t)bin_to_uint32(src); - src += sizeof(uint32_t); - src += skip_padding(src); - - if (irep->ilen > 0) { - if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) { - return NULL; - } - if ((flags & FLAG_SRC_MALLOC) == 0 && - (flags & FLAG_BYTEORDER_NATIVE)) { - irep->iseq = (mrb_code*)src; - src += sizeof(uint32_t) * irep->ilen; - irep->flags |= MRB_ISEQ_NO_FREE; - } - else { - irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); - if (flags & FLAG_BYTEORDER_NATIVE) { - memcpy(irep->iseq, src, sizeof(uint32_t) * irep->ilen); - src += sizeof(uint32_t) * irep->ilen; - } - else if (flags & FLAG_BYTEORDER_BIG) { - for (i = 0; i < irep->ilen; i++) { - irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */ - src += sizeof(uint32_t); - } - } - else { - for (i = 0; i < irep->ilen; i++) { - irep->iseq[i] = (mrb_code)bin_to_uint32l(src); /* iseq */ - src += sizeof(uint32_t); - } - } - } - } - - /* POOL BLOCK */ - plen = bin_to_uint32(src); /* number of pool */ - src += sizeof(uint32_t); - if (plen > 0) { - if (SIZE_ERROR_MUL(plen, sizeof(mrb_value))) { - return NULL; - } - irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * plen); - - for (i = 0; i < plen; i++) { - mrb_value s; - - tt = *src++; /* pool TT */ - pool_data_len = bin_to_uint16(src); /* pool data length */ - src += sizeof(uint16_t); - if (flags & FLAG_SRC_MALLOC) { - s = mrb_str_new(mrb, (char *)src, pool_data_len); - } - else { - s = mrb_str_new_static(mrb, (char *)src, pool_data_len); - } - src += pool_data_len; - switch (tt) { /* pool data */ - case IREP_TT_FIXNUM: - irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE); - break; - - case IREP_TT_FLOAT: - irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE)); - break; - - case IREP_TT_STRING: - irep->pool[i] = mrb_str_pool(mrb, s); - break; - - default: - /* should not happen */ - irep->pool[i] = mrb_nil_value(); - break; - } - irep->plen++; - mrb_gc_arena_restore(mrb, ai); - } - } - - /* SYMS BLOCK */ - irep->slen = (size_t)bin_to_uint32(src); /* syms length */ - src += sizeof(uint32_t); - if (irep->slen > 0) { - if (SIZE_ERROR_MUL(irep->slen, sizeof(mrb_sym))) { - return NULL; - } - irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); - - for (i = 0; i < irep->slen; i++) { - snl = bin_to_uint16(src); /* symbol name length */ - src += sizeof(uint16_t); - - if (snl == MRB_DUMP_NULL_SYM_LEN) { - irep->syms[i] = 0; - continue; - } - - if (flags & FLAG_SRC_MALLOC) { - irep->syms[i] = mrb_intern(mrb, (char *)src, snl); - } - else { - irep->syms[i] = mrb_intern_static(mrb, (char *)src, snl); - } - src += snl + 1; - - mrb_gc_arena_restore(mrb, ai); - } - } - - irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen); - - diff = src - bin; - mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); - *len = (size_t)diff; - - return irep; -} - -static mrb_irep* -read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) -{ - mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags); - int i; - - if (irep == NULL) { - return NULL; - } - - bin += *len; - for (i=0; i<irep->rlen; i++) { - size_t rlen; - - irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags); - if (irep->reps[i] == NULL) { - return NULL; - } - bin += rlen; - *len += rlen; - } - return irep; -} - -static mrb_irep* -read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) -{ - size_t len; - - bin += sizeof(struct rite_section_irep_header); - return read_irep_record(mrb, bin, &len, flags); -} - -static int -read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len) -{ - size_t i, fname_len, niseq; - char *fname; - uint16_t *lines; - - *len = 0; - bin += sizeof(uint32_t); /* record size */ - *len += sizeof(uint32_t); - fname_len = bin_to_uint16(bin); - bin += sizeof(uint16_t); - *len += sizeof(uint16_t); - fname = (char *)mrb_malloc(mrb, fname_len + 1); - memcpy(fname, bin, fname_len); - fname[fname_len] = '\0'; - bin += fname_len; - *len += fname_len; - - niseq = (size_t)bin_to_uint32(bin); - bin += sizeof(uint32_t); /* niseq */ - *len += sizeof(uint32_t); - - if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) { - return MRB_DUMP_GENERAL_FAILURE; - } - lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t)); - for (i = 0; i < niseq; i++) { - lines[i] = bin_to_uint16(bin); - bin += sizeof(uint16_t); /* niseq */ - *len += sizeof(uint16_t); - } - - irep->filename = fname; - irep->lines = lines; - return MRB_DUMP_OK; -} - -static int -read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp) -{ - int result = read_lineno_record_1(mrb, bin, irep, lenp); - int i; - - if (result != MRB_DUMP_OK) return result; - for (i = 0; i < irep->rlen; i++) { - size_t len; - - result = read_lineno_record(mrb, bin, irep->reps[i], &len); - if (result != MRB_DUMP_OK) break; - bin += len; - *lenp += len; - } - return result; -} - -static int -read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep) -{ - size_t len; - - len = 0; - bin += sizeof(struct rite_section_lineno_header); - - /* Read Binary Data Section */ - return read_lineno_record(mrb, bin, irep, &len); -} - -static int -read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len) -{ - const uint8_t *bin = start; - ptrdiff_t diff; - size_t record_size; - uint16_t f_idx; - int i; - - if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; } - - irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); - irep->debug_info->pc_count = (uint32_t)irep->ilen; - - record_size = (size_t)bin_to_uint32(bin); - bin += sizeof(uint32_t); - - irep->debug_info->flen = bin_to_uint16(bin); - irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen); - bin += sizeof(uint16_t); - - for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { - mrb_irep_debug_info_file *file; - uint16_t filename_idx; - mrb_int len; - - file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); - irep->debug_info->files[f_idx] = file; - - file->start_pos = bin_to_uint32(bin); - bin += sizeof(uint32_t); - - /* filename */ - filename_idx = bin_to_uint16(bin); - bin += sizeof(uint16_t); - mrb_assert(filename_idx < filenames_len); - file->filename_sym = filenames[filename_idx]; - len = 0; - file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); - - file->line_entry_count = bin_to_uint32(bin); - bin += sizeof(uint32_t); - file->line_type = (mrb_debug_line_type)bin_to_uint8(bin); - bin += sizeof(uint8_t); - switch (file->line_type) { - case mrb_debug_line_ary: { - uint32_t l; - - file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count)); - for (l = 0; l < file->line_entry_count; ++l) { - file->lines.ary[l] = bin_to_uint16(bin); - bin += sizeof(uint16_t); - } - } break; - - case mrb_debug_line_flat_map: { - uint32_t l; - - file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc( - mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count)); - for (l = 0; l < file->line_entry_count; ++l) { - file->lines.flat_map[l].start_pos = bin_to_uint32(bin); - bin += sizeof(uint32_t); - file->lines.flat_map[l].line = bin_to_uint16(bin); - bin += sizeof(uint16_t); - } - } break; - - default: return MRB_DUMP_GENERAL_FAILURE; - } - } - - diff = bin - start; - mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); - - if (record_size != (size_t)diff) { - return MRB_DUMP_GENERAL_FAILURE; - } - - for (i = 0; i < irep->rlen; i++) { - size_t len; - int ret; - - ret = read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_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_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) -{ - const uint8_t *bin; - ptrdiff_t diff; - struct rite_section_debug_header *header; - uint16_t i; - size_t len = 0; - int result; - uint16_t filenames_len; - mrb_sym *filenames; - - bin = start; - header = (struct rite_section_debug_header *)bin; - bin += sizeof(struct rite_section_debug_header); - - filenames_len = bin_to_uint16(bin); - bin += sizeof(uint16_t); - filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len); - for (i = 0; i < filenames_len; ++i) { - uint16_t f_len = bin_to_uint16(bin); - bin += sizeof(uint16_t); - if (flags & FLAG_SRC_MALLOC) { - filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); - } - else { - filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len); - } - bin += f_len; - } - - result = read_debug_record(mrb, bin, irep, &len, filenames, filenames_len); - if (result != MRB_DUMP_OK) goto debug_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; - } - -debug_exit: - mrb_free(mrb, filenames); - return result; -} - -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; - ptrdiff_t diff; - int i; - - 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, uint8_t flags) -{ - 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) = - (flags & FLAG_SRC_MALLOC)? 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, uint8_t *flags) -{ - const struct rite_binary_header *header = (const struct rite_binary_header *)bin; - - 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 { - return MRB_DUMP_INVALID_FILE_HEADER; - } - - if (crc) { - *crc = bin_to_uint16(header->binary_crc); - } - *bin_size = (size_t)bin_to_uint32(header->binary_size); - - return MRB_DUMP_OK; -} - -static mrb_irep* -read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) -{ - int result; - mrb_irep *irep = NULL; - const struct rite_section_header *section_header; - uint16_t crc; - size_t bin_size = 0; - size_t n; - - if ((mrb == NULL) || (bin == NULL)) { - return NULL; - } - - result = read_binary_header(bin, &bin_size, &crc, &flags); - if (result != MRB_DUMP_OK) { - return NULL; - } - - n = offset_crc_body(); - if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) { - return NULL; - } - - bin += sizeof(struct rite_binary_header); - do { - section_header = (const struct rite_section_header *)bin; - if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) { - irep = read_section_irep(mrb, bin, flags); - if (!irep) return NULL; - } - else if (memcmp(section_header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(section_header->section_ident)) == 0) { - if (!irep) return NULL; /* corrupted data */ - result = read_section_lineno(mrb, bin, irep); - if (result < MRB_DUMP_OK) { - return NULL; - } - } - else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) { - if (!irep) return NULL; /* corrupted data */ - result = read_section_debug(mrb, bin, irep, flags); - if (result < MRB_DUMP_OK) { - return NULL; - } - } - else if (memcmp(section_header->section_ident, RITE_SECTION_LV_IDENT, sizeof(section_header->section_ident)) == 0) { - if (!irep) return NULL; - result = read_section_lv(mrb, bin, irep, flags); - if (result < MRB_DUMP_OK) { - return NULL; - } - } - bin += bin_to_uint32(section_header->section_size); - } while (memcmp(section_header->section_ident, RITE_BINARY_EOF, sizeof(section_header->section_ident)) != 0); - - return irep; -} - -mrb_irep* -mrb_read_irep(mrb_state *mrb, const uint8_t *bin) -{ -#ifdef MRB_USE_ETEXT_EDATA - uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC; -#else - uint8_t flags = FLAG_SRC_STATIC; -#endif - - return read_irep(mrb, bin, flags); -} - -void mrb_exc_set(mrb_state *mrb, mrb_value exc); - -static void -irep_error(mrb_state *mrb) -{ - mrb_exc_set(mrb, mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error")); -} - -void mrb_codedump_all(mrb_state*, struct RProc*); - -static mrb_value -load_irep(mrb_state *mrb, mrb_irep *irep, mrbc_context *c) -{ - struct RProc *proc; - - if (!irep) { - irep_error(mrb); - return mrb_nil_value(); - } - proc = mrb_proc_new(mrb, irep); - proc->c = NULL; - mrb_irep_decref(mrb, irep); - if (c && c->dump_result) mrb_codedump_all(mrb, proc); - if (c && c->no_exec) return mrb_obj_value(proc); - return mrb_top_run(mrb, proc, mrb_top_self(mrb), 0); -} - -MRB_API mrb_value -mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c) -{ - return load_irep(mrb, mrb_read_irep(mrb, bin), c); -} - -MRB_API mrb_value -mrb_load_irep(mrb_state *mrb, const uint8_t *bin) -{ - return mrb_load_irep_cxt(mrb, bin, NULL); -} - -#ifndef MRB_DISABLE_STDIO - -mrb_irep* -mrb_read_irep_file(mrb_state *mrb, FILE* fp) -{ - mrb_irep *irep = NULL; - uint8_t *buf; - const size_t header_size = sizeof(struct rite_binary_header); - size_t buf_size = 0; - uint8_t flags = 0; - int result; - - if ((mrb == NULL) || (fp == NULL)) { - return NULL; - } - - buf = (uint8_t*)mrb_malloc(mrb, header_size); - if (fread(buf, header_size, 1, fp) == 0) { - goto irep_exit; - } - result = read_binary_header(buf, &buf_size, NULL, &flags); - if (result != MRB_DUMP_OK || buf_size <= header_size) { - goto irep_exit; - } - - buf = (uint8_t*)mrb_realloc(mrb, buf, buf_size); - if (fread(buf+header_size, buf_size-header_size, 1, fp) == 0) { - goto irep_exit; - } - irep = read_irep(mrb, buf, FLAG_SRC_MALLOC); - -irep_exit: - mrb_free(mrb, buf); - return irep; -} - -MRB_API mrb_value -mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c) -{ - return load_irep(mrb, mrb_read_irep_file(mrb, fp), c); -} - -MRB_API mrb_value -mrb_load_irep_file(mrb_state *mrb, FILE* fp) -{ - return mrb_load_irep_file_cxt(mrb, fp, NULL); -} -#endif /* MRB_DISABLE_STDIO */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/mruby_core.rake b/web/server/h2o/libh2o/deps/mruby/src/mruby_core.rake deleted file mode 100644 index 4558493d9..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/mruby_core.rake +++ /dev/null @@ -1,19 +0,0 @@ -MRuby.each_target do - current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) - relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) - current_build_dir = "#{build_dir}/#{relative_from_root}" - - objs = Dir.glob("#{current_dir}/*.c").map { |f| - next nil if cxx_exception_enabled? and f =~ /(error|vm).c$/ - objfile(f.pathmap("#{current_build_dir}/%n")) - }.compact - - if cxx_exception_enabled? - objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" } - end - self.libmruby << objs - - file libfile("#{build_dir}/lib/libmruby_core") => objs do |t| - archiver.run t.name, t.prerequisites - end -end diff --git a/web/server/h2o/libh2o/deps/mruby/src/numeric.c b/web/server/h2o/libh2o/deps/mruby/src/numeric.c deleted file mode 100644 index afb8415a0..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/numeric.c +++ /dev/null @@ -1,1355 +0,0 @@ -/* -** numeric.c - Numeric, Integer, Float, Fixnum class -** -** See Copyright Notice in mruby.h -*/ - -#include <float.h> -#include <limits.h> -#include <math.h> -#include <stdlib.h> - -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/numeric.h> -#include <mruby/string.h> -#include <mruby/class.h> - -#ifdef MRB_USE_FLOAT -#define trunc(f) truncf(f) -#define floor(f) floorf(f) -#define ceil(f) ceilf(f) -#define fmod(x,y) fmodf(x,y) -#define MRB_FLO_TO_STR_FMT "%.7g" -#else -#define MRB_FLO_TO_STR_FMT "%.14g" -#endif - -MRB_API mrb_float -mrb_to_flo(mrb_state *mrb, mrb_value val) -{ - switch (mrb_type(val)) { - case MRB_TT_FIXNUM: - return (mrb_float)mrb_fixnum(val); - case MRB_TT_FLOAT: - break; - default: - mrb_raise(mrb, E_TYPE_ERROR, "non float value"); - } - return mrb_float(val); -} - -/* - * call-seq: - * - * num ** other -> num - * - * Raises <code>num</code> the <code>other</code> power. - * - * 2.0**3 #=> 8.0 - */ -static mrb_value -num_pow(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - mrb_float d; - - mrb_get_args(mrb, "o", &y); - if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) { - /* try ipow() */ - mrb_int base = mrb_fixnum(x); - mrb_int exp = mrb_fixnum(y); - mrb_int result = 1; - - if (exp < 0) goto float_pow; - for (;;) { - if (exp & 1) { - if (mrb_int_mul_overflow(result, base, &result)) { - goto float_pow; - } - } - exp >>= 1; - if (exp == 0) break; - if (mrb_int_mul_overflow(base, base, &base)) { - goto float_pow; - } - } - return mrb_fixnum_value(result); - } - float_pow: - d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); - return mrb_float_value(mrb, d); -} - -/* 15.2.8.3.4 */ -/* 15.2.9.3.4 */ -/* - * call-seq: - * num / other -> num - * - * Performs division: the class of the resulting object depends on - * the class of <code>num</code> and on the magnitude of the - * result. - */ - -mrb_value -mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) -{ - return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); -} - -/* 15.2.9.3.19(x) */ -/* - * call-seq: - * num.quo(numeric) -> real - * - * Returns most exact division. - */ - -static mrb_value -num_div(mrb_state *mrb, mrb_value x) -{ - mrb_float y; - - mrb_get_args(mrb, "f", &y); - return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); -} - -/******************************************************************** - * - * Document-class: Float - * - * <code>Float</code> objects represent inexact real numbers using - * the native architecture's double-precision floating point - * representation. - */ - -/* 15.2.9.3.16(x) */ -/* - * call-seq: - * flt.to_s -> string - * - * Returns a string containing a representation of self. As well as a - * fixed or exponential form of the number, the call may return - * "<code>NaN</code>", "<code>Infinity</code>", and - * "<code>-Infinity</code>". - */ - -static mrb_value -flo_to_s(mrb_state *mrb, mrb_value flt) -{ - if (isnan(mrb_float(flt))) { - return mrb_str_new_lit(mrb, "NaN"); - } - return mrb_float_to_str(mrb, flt, MRB_FLO_TO_STR_FMT); -} - -/* 15.2.9.3.2 */ -/* - * call-seq: - * float - other -> float - * - * Returns a new float which is the difference of <code>float</code> - * and <code>other</code>. - */ - -static mrb_value -flo_minus(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y)); -} - -/* 15.2.9.3.3 */ -/* - * call-seq: - * float * other -> float - * - * Returns a new float which is the product of <code>float</code> - * and <code>other</code>. - */ - -static mrb_value -flo_mul(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); -} - -static void -flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp) -{ - mrb_float div; - mrb_float mod; - - if (y == 0.0) { - if (x > 0.0) div = INFINITY; - else if (x < 0.0) div = -INFINITY; - else div = NAN; /* x == 0.0 */ - mod = NAN; - } - else { - mod = fmod(x, y); - if (isinf(x) && isfinite(y)) - div = x; - else - div = (x - mod) / y; - if (y*mod < 0) { - mod += y; - div -= 1.0; - } - } - - if (modp) *modp = mod; - if (divp) *divp = div; -} - -/* 15.2.9.3.5 */ -/* - * call-seq: - * flt % other -> float - * flt.modulo(other) -> float - * - * Return the modulo after division of <code>flt</code> by <code>other</code>. - * - * 6543.21.modulo(137) #=> 104.21 - * 6543.21.modulo(137.24) #=> 92.9299999999996 - */ - -static mrb_value -flo_mod(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - mrb_float mod; - - mrb_get_args(mrb, "o", &y); - - flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod); - return mrb_float_value(mrb, mod); -} - -/* 15.2.8.3.16 */ -/* - * call-seq: - * num.eql?(numeric) -> true or false - * - * Returns <code>true</code> if <i>num</i> and <i>numeric</i> are the - * same type and have equal values. - * - * 1 == 1.0 #=> true - * 1.eql?(1.0) #=> false - * (1.0).eql?(1.0) #=> true - */ -static mrb_value -fix_eql(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - if (!mrb_fixnum_p(y)) return mrb_false_value(); - return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); -} - -static mrb_value -flo_eql(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - if (!mrb_float_p(y)) return mrb_false_value(); - return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y)); -} - -/* 15.2.9.3.7 */ -/* - * call-seq: - * flt == obj -> true or false - * - * Returns <code>true</code> only if <i>obj</i> has the same value - * as <i>flt</i>. Contrast this with <code>Float#eql?</code>, which - * requires <i>obj</i> to be a <code>Float</code>. - * - * 1.0 == 1 #=> true - * - */ - -static mrb_value -flo_eq(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - mrb_get_args(mrb, "o", &y); - - switch (mrb_type(y)) { - case MRB_TT_FIXNUM: - return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y)); - case MRB_TT_FLOAT: - return mrb_bool_value(mrb_float(x) == mrb_float(y)); - default: - return mrb_false_value(); - } -} - -static int64_t -value_int64(mrb_state *mrb, mrb_value x) -{ - switch (mrb_type(x)) { - case MRB_TT_FIXNUM: - return (int64_t)mrb_fixnum(x); - break; - case MRB_TT_FLOAT: - return (int64_t)mrb_float(x); - default: - mrb_raise(mrb, E_TYPE_ERROR, "cannot convert to Integer"); - break; - } - /* not reached */ - return 0; -} - -static mrb_value -int64_value(mrb_state *mrb, int64_t v) -{ - if (FIXABLE(v)) { - return mrb_fixnum_value((mrb_int)v); - } - return mrb_float_value(mrb, (mrb_float)v); -} - -static mrb_value -flo_rev(mrb_state *mrb, mrb_value x) -{ - int64_t v1; - mrb_get_args(mrb, ""); - v1 = (int64_t)mrb_float(x); - return int64_value(mrb, ~v1); -} - -static mrb_value -flo_and(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - int64_t v1, v2; - mrb_get_args(mrb, "o", &y); - - v1 = (int64_t)mrb_float(x); - v2 = value_int64(mrb, y); - return int64_value(mrb, v1 & v2); -} - -static mrb_value -flo_or(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - int64_t v1, v2; - mrb_get_args(mrb, "o", &y); - - v1 = (int64_t)mrb_float(x); - v2 = value_int64(mrb, y); - return int64_value(mrb, v1 | v2); -} - -static mrb_value -flo_xor(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - int64_t v1, v2; - mrb_get_args(mrb, "o", &y); - - v1 = (int64_t)mrb_float(x); - v2 = value_int64(mrb, y); - return int64_value(mrb, v1 ^ v2); -} - -static mrb_value -flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) -{ - mrb_float val; - - if (width == 0) { - return x; - } - val = mrb_float(x); - if (width < 0) { - while (width++) { - val /= 2; - } -#if defined(_ISOC99_SOURCE) - val = trunc(val); -#else - if (val > 0){ - val = floor(val); - } else { - val = ceil(val); - } -#endif - if (val == 0 && mrb_float(x) < 0) { - return mrb_fixnum_value(-1); - } - } - else { - while (width--) { - val *= 2; - } - } - if (FIXABLE_FLOAT(val)) { - return mrb_fixnum_value((mrb_int)val); - } - return mrb_float_value(mrb, val); -} - -static mrb_value -flo_lshift(mrb_state *mrb, mrb_value x) -{ - mrb_int width; - - mrb_get_args(mrb, "i", &width); - return flo_shift(mrb, x, -width); -} - -static mrb_value -flo_rshift(mrb_state *mrb, mrb_value x) -{ - mrb_int width; - - mrb_get_args(mrb, "i", &width); - return flo_shift(mrb, x, width); -} - -/* 15.2.9.3.13 */ -/* - * call-seq: - * flt.to_f -> self - * - * As <code>flt</code> is already a float, returns +self+. - */ - -static mrb_value -flo_to_f(mrb_state *mrb, mrb_value num) -{ - return num; -} - -/* 15.2.9.3.11 */ -/* - * call-seq: - * flt.infinite? -> nil, -1, +1 - * - * Returns <code>nil</code>, -1, or +1 depending on whether <i>flt</i> - * is finite, -infinity, or +infinity. - * - * (0.0).infinite? #=> nil - * (-1.0/0.0).infinite? #=> -1 - * (+1.0/0.0).infinite? #=> 1 - */ - -static mrb_value -flo_infinite_p(mrb_state *mrb, mrb_value num) -{ - mrb_float value = mrb_float(num); - - if (isinf(value)) { - return mrb_fixnum_value(value < 0 ? -1 : 1); - } - return mrb_nil_value(); -} - -/* 15.2.9.3.9 */ -/* - * call-seq: - * flt.finite? -> true or false - * - * Returns <code>true</code> if <i>flt</i> is a valid IEEE floating - * point number (it is not infinite, and <code>nan?</code> is - * <code>false</code>). - * - */ - -static mrb_value -flo_finite_p(mrb_state *mrb, mrb_value num) -{ - return mrb_bool_value(isfinite(mrb_float(num))); -} - -void -mrb_check_num_exact(mrb_state *mrb, mrb_float num) -{ - if (isinf(num)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, num < 0 ? "-Infinity" : "Infinity"); - } - if (isnan(num)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); - } -} - -/* 15.2.9.3.10 */ -/* - * call-seq: - * flt.floor -> integer - * - * Returns the largest integer less than or equal to <i>flt</i>. - * - * 1.2.floor #=> 1 - * 2.0.floor #=> 2 - * (-1.2).floor #=> -2 - * (-2.0).floor #=> -2 - */ - -static mrb_value -flo_floor(mrb_state *mrb, mrb_value num) -{ - mrb_float f = floor(mrb_float(num)); - - mrb_check_num_exact(mrb, f); - if (!FIXABLE_FLOAT(f)) { - return mrb_float_value(mrb, f); - } - return mrb_fixnum_value((mrb_int)f); -} - -/* 15.2.9.3.8 */ -/* - * call-seq: - * flt.ceil -> integer - * - * Returns the smallest <code>Integer</code> greater than or equal to - * <i>flt</i>. - * - * 1.2.ceil #=> 2 - * 2.0.ceil #=> 2 - * (-1.2).ceil #=> -1 - * (-2.0).ceil #=> -2 - */ - -static mrb_value -flo_ceil(mrb_state *mrb, mrb_value num) -{ - mrb_float f = ceil(mrb_float(num)); - - mrb_check_num_exact(mrb, f); - if (!FIXABLE_FLOAT(f)) { - return mrb_float_value(mrb, f); - } - return mrb_fixnum_value((mrb_int)f); -} - -/* 15.2.9.3.12 */ -/* - * call-seq: - * flt.round([ndigits]) -> integer or float - * - * Rounds <i>flt</i> to a given precision in decimal digits (default 0 digits). - * Precision may be negative. Returns a floating point number when ndigits - * is more than zero. - * - * 1.4.round #=> 1 - * 1.5.round #=> 2 - * 1.6.round #=> 2 - * (-1.5).round #=> -2 - * - * 1.234567.round(2) #=> 1.23 - * 1.234567.round(3) #=> 1.235 - * 1.234567.round(4) #=> 1.2346 - * 1.234567.round(5) #=> 1.23457 - * - * 34567.89.round(-5) #=> 0 - * 34567.89.round(-4) #=> 30000 - * 34567.89.round(-3) #=> 35000 - * 34567.89.round(-2) #=> 34600 - * 34567.89.round(-1) #=> 34570 - * 34567.89.round(0) #=> 34568 - * 34567.89.round(1) #=> 34567.9 - * 34567.89.round(2) #=> 34567.89 - * 34567.89.round(3) #=> 34567.89 - * - */ - -static mrb_value -flo_round(mrb_state *mrb, mrb_value num) -{ - double number, f; - mrb_int ndigits = 0; - mrb_int i; - - mrb_get_args(mrb, "|i", &ndigits); - number = mrb_float(num); - - if (0 < ndigits && (isinf(number) || isnan(number))) { - return num; - } - mrb_check_num_exact(mrb, number); - - f = 1.0; - i = ndigits >= 0 ? ndigits : -ndigits; - while (--i >= 0) - f = f*10.0; - - if (isinf(f)) { - if (ndigits < 0) number = 0; - } - else { - double d; - - if (ndigits < 0) number /= f; - else number *= f; - - /* home-made inline implementation of round(3) */ - if (number > 0.0) { - d = floor(number); - number = d + (number - d >= 0.5); - } - else if (number < 0.0) { - d = ceil(number); - number = d - (d - number >= 0.5); - } - - if (ndigits < 0) number *= f; - else number /= f; - } - - if (ndigits > 0) { - if (!isfinite(number)) return num; - return mrb_float_value(mrb, number); - } - return mrb_fixnum_value((mrb_int)number); -} - -/* 15.2.9.3.14 */ -/* 15.2.9.3.15 */ -/* - * call-seq: - * flt.to_i -> integer - * flt.to_int -> integer - * flt.truncate -> integer - * - * Returns <i>flt</i> truncated to an <code>Integer</code>. - */ - -static mrb_value -flo_truncate(mrb_state *mrb, mrb_value num) -{ - mrb_float f = mrb_float(num); - - if (f > 0.0) f = floor(f); - if (f < 0.0) f = ceil(f); - - mrb_check_num_exact(mrb, f); - if (!FIXABLE_FLOAT(f)) { - return mrb_float_value(mrb, f); - } - return mrb_fixnum_value((mrb_int)f); -} - -static mrb_value -flo_nan_p(mrb_state *mrb, mrb_value num) -{ - return mrb_bool_value(isnan(mrb_float(num))); -} - -/* - * Document-class: Integer - * - * <code>Integer</code> is the basis for the two concrete classes that - * hold whole numbers, <code>Bignum</code> and <code>Fixnum</code>. - * - */ - - -/* - * call-seq: - * int.to_i -> integer - * int.to_int -> integer - * - * As <i>int</i> is already an <code>Integer</code>, all these - * methods simply return the receiver. - */ - -static mrb_value -int_to_i(mrb_state *mrb, mrb_value num) -{ - return num; -} - -mrb_value -mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) -{ - mrb_int a; - - a = mrb_fixnum(x); - if (mrb_fixnum_p(y)) { - mrb_int b, c; - - if (a == 0) return x; - b = mrb_fixnum(y); - if (mrb_int_mul_overflow(a, b, &c)) { - return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b); - } - return mrb_fixnum_value(c); - } - return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); -} - -/* 15.2.8.3.3 */ -/* - * call-seq: - * fix * numeric -> numeric_result - * - * Performs multiplication: the class of the resulting object depends on - * the class of <code>numeric</code> and on the magnitude of the - * result. - */ - -static mrb_value -fix_mul(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - return mrb_fixnum_mul(mrb, x, y); -} - -static void -fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) -{ - mrb_int div, mod; - - /* TODO: add mrb_assert(y != 0) to make sure */ - - if (y < 0) { - if (x < 0) - div = -x / -y; - else - div = - (x / -y); - } - else { - if (x < 0) - div = - (-x / y); - else - div = x / y; - } - mod = x - div*y; - if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) { - mod += y; - div -= 1; - } - if (divp) *divp = div; - if (modp) *modp = mod; -} - -/* 15.2.8.3.5 */ -/* - * call-seq: - * fix % other -> real - * fix.modulo(other) -> real - * - * Returns <code>fix</code> modulo <code>other</code>. - * See <code>numeric.divmod</code> for more information. - */ - -static mrb_value -fix_mod(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - mrb_int a; - - mrb_get_args(mrb, "o", &y); - a = mrb_fixnum(x); - if (mrb_fixnum_p(y)) { - mrb_int b, mod; - - if ((b=mrb_fixnum(y)) == 0) { - return mrb_float_value(mrb, NAN); - } - fixdivmod(mrb, a, b, 0, &mod); - return mrb_fixnum_value(mod); - } - else { - mrb_float mod; - - flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); - return mrb_float_value(mrb, mod); - } -} - -/* - * call-seq: - * fix.divmod(numeric) -> array - * - * See <code>Numeric#divmod</code>. - */ -static mrb_value -fix_divmod(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - - if (mrb_fixnum_p(y)) { - mrb_int div, mod; - - if (mrb_fixnum(y) == 0) { - return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ? - mrb_float_value(mrb, NAN): - mrb_float_value(mrb, INFINITY)), - mrb_float_value(mrb, NAN)); - } - fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); - return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); - } - else { - mrb_float div, mod; - mrb_value a, b; - - flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod); - a = mrb_float_value(mrb, div); - b = mrb_float_value(mrb, mod); - return mrb_assoc_new(mrb, a, b); - } -} - -static mrb_value -flo_divmod(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - mrb_float div, mod; - mrb_value a, b; - - mrb_get_args(mrb, "o", &y); - - flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod); - a = mrb_float_value(mrb, div); - b = mrb_float_value(mrb, mod); - return mrb_assoc_new(mrb, a, b); -} - -/* 15.2.8.3.7 */ -/* - * call-seq: - * fix == other -> true or false - * - * Return <code>true</code> if <code>fix</code> equals <code>other</code> - * numerically. - * - * 1 == 2 #=> false - * 1 == 1.0 #=> true - */ - -static mrb_value -fix_equal(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - switch (mrb_type(y)) { - case MRB_TT_FIXNUM: - return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); - case MRB_TT_FLOAT: - return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y)); - default: - return mrb_false_value(); - } -} - -/* 15.2.8.3.8 */ -/* - * call-seq: - * ~fix -> integer - * - * One's complement: returns a number where each bit is flipped. - * ex.0---00001 (1)-> 1---11110 (-2) - * ex.0---00010 (2)-> 1---11101 (-3) - * ex.0---00100 (4)-> 1---11011 (-5) - */ - -static mrb_value -fix_rev(mrb_state *mrb, mrb_value num) -{ - mrb_int val = mrb_fixnum(num); - - return mrb_fixnum_value(~val); -} - -static mrb_value flo_and(mrb_state *mrb, mrb_value x); -static mrb_value flo_or(mrb_state *mrb, mrb_value x); -static mrb_value flo_xor(mrb_state *mrb, mrb_value x); -#define bit_op(x,y,op1,op2) do {\ - if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\ - return flo_ ## op1(mrb, mrb_float_value(mrb, mrb_fixnum(x)));\ -} while(0) - -/* 15.2.8.3.9 */ -/* - * call-seq: - * fix & integer -> integer_result - * - * Bitwise AND. - */ - -static mrb_value -fix_and(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - bit_op(x, y, and, &); -} - -/* 15.2.8.3.10 */ -/* - * call-seq: - * fix | integer -> integer_result - * - * Bitwise OR. - */ - -static mrb_value -fix_or(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - bit_op(x, y, or, |); -} - -/* 15.2.8.3.11 */ -/* - * call-seq: - * fix ^ integer -> integer_result - * - * Bitwise EXCLUSIVE OR. - */ - -static mrb_value -fix_xor(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - bit_op(x, y, or, ^); -} - -#define NUMERIC_SHIFT_WIDTH_MAX (MRB_INT_BIT-1) - -static mrb_value -lshift(mrb_state *mrb, mrb_int val, mrb_int width) -{ - if (width < 0) { /* mrb_int overflow */ - return mrb_float_value(mrb, INFINITY); - } - if (val > 0) { - if ((width > NUMERIC_SHIFT_WIDTH_MAX) || - (val > (MRB_INT_MAX >> width))) { - goto bit_overflow; - } - return mrb_fixnum_value(val << width); - } - else { - if ((width > NUMERIC_SHIFT_WIDTH_MAX) || - (val < (MRB_INT_MIN >> width))) { - goto bit_overflow; - } - return mrb_fixnum_value(val * (1u << width)); - } - -bit_overflow: - { - mrb_float f = (mrb_float)val; - while (width--) { - f *= 2; - } - return mrb_float_value(mrb, f); - } -} - -static mrb_value -rshift(mrb_int val, mrb_int width) -{ - if (width < 0) { /* mrb_int overflow */ - return mrb_fixnum_value(0); - } - if (width >= NUMERIC_SHIFT_WIDTH_MAX) { - if (val < 0) { - return mrb_fixnum_value(-1); - } - return mrb_fixnum_value(0); - } - return mrb_fixnum_value(val >> width); -} - -/* 15.2.8.3.12 */ -/* - * call-seq: - * fix << count -> integer or float - * - * Shifts _fix_ left _count_ positions (right if _count_ is negative). - */ - -static mrb_value -fix_lshift(mrb_state *mrb, mrb_value x) -{ - mrb_int width, val; - - mrb_get_args(mrb, "i", &width); - if (width == 0) { - return x; - } - val = mrb_fixnum(x); - if (val == 0) return x; - if (width < 0) { - return rshift(val, -width); - } - return lshift(mrb, val, width); -} - -/* 15.2.8.3.13 */ -/* - * call-seq: - * fix >> count -> integer or float - * - * Shifts _fix_ right _count_ positions (left if _count_ is negative). - */ - -static mrb_value -fix_rshift(mrb_state *mrb, mrb_value x) -{ - mrb_int width, val; - - mrb_get_args(mrb, "i", &width); - if (width == 0) { - return x; - } - val = mrb_fixnum(x); - if (val == 0) return x; - if (width < 0) { - return lshift(mrb, val, -width); - } - return rshift(val, width); -} - -/* 15.2.8.3.23 */ -/* - * call-seq: - * fix.to_f -> float - * - * Converts <i>fix</i> to a <code>Float</code>. - * - */ - -static mrb_value -fix_to_f(mrb_state *mrb, mrb_value num) -{ - return mrb_float_value(mrb, (mrb_float)mrb_fixnum(num)); -} - -/* - * Document-class: FloatDomainError - * - * Raised when attempting to convert special float values - * (in particular infinite or NaN) - * to numerical classes which don't support them. - * - * Float::INFINITY.to_r - * - * <em>raises the exception:</em> - * - * FloatDomainError: Infinity - */ -/* ------------------------------------------------------------------------*/ -MRB_API mrb_value -mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) -{ - mrb_int z = 0; - - if (!mrb_float_p(x)) { - mrb_raise(mrb, E_TYPE_ERROR, "non float value"); - z = 0; /* not reached. just suppress warnings. */ - } - else { - mrb_float d = mrb_float(x); - - if (isinf(d)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); - } - if (isnan(d)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); - } - if (FIXABLE_FLOAT(d)) { - z = (mrb_int)d; - } - else { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "number (%S) too big for integer", x); - } - } - return mrb_fixnum_value(z); -} - -mrb_value -mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) -{ - mrb_int a; - - a = mrb_fixnum(x); - if (mrb_fixnum_p(y)) { - mrb_int b, c; - - if (a == 0) return y; - b = mrb_fixnum(y); - if (mrb_int_add_overflow(a, b, &c)) { - return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); - } - return mrb_fixnum_value(c); - } - return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); -} - -/* 15.2.8.3.1 */ -/* - * call-seq: - * fix + numeric -> numeric_result - * - * Performs addition: the class of the resulting object depends on - * the class of <code>numeric</code> and on the magnitude of the - * result. - */ -static mrb_value -fix_plus(mrb_state *mrb, mrb_value self) -{ - mrb_value other; - - mrb_get_args(mrb, "o", &other); - return mrb_fixnum_plus(mrb, self, other); -} - -mrb_value -mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) -{ - mrb_int a; - - a = mrb_fixnum(x); - if (mrb_fixnum_p(y)) { - mrb_int b, c; - - b = mrb_fixnum(y); - if (mrb_int_sub_overflow(a, b, &c)) { - return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); - } - return mrb_fixnum_value(c); - } - return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); -} - -/* 15.2.8.3.2 */ -/* 15.2.8.3.16 */ -/* - * call-seq: - * fix - numeric -> numeric_result - * - * Performs subtraction: the class of the resulting object depends on - * the class of <code>numeric</code> and on the magnitude of the - * result. - */ -static mrb_value -fix_minus(mrb_state *mrb, mrb_value self) -{ - mrb_value other; - - mrb_get_args(mrb, "o", &other); - return mrb_fixnum_minus(mrb, self, other); -} - - -MRB_API mrb_value -mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base) -{ - char buf[MRB_INT_BIT+1]; - char *b = buf + sizeof buf; - mrb_int val = mrb_fixnum(x); - - if (base < 2 || 36 < base) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base)); - } - - if (val == 0) { - *--b = '0'; - } - else if (val < 0) { - do { - *--b = mrb_digitmap[-(val % base)]; - } while (val /= base); - *--b = '-'; - } - else { - do { - *--b = mrb_digitmap[(int)(val % base)]; - } while (val /= base); - } - - return mrb_str_new(mrb, b, buf + sizeof(buf) - b); -} - -/* 15.2.8.3.25 */ -/* - * call-seq: - * fix.to_s(base=10) -> string - * - * Returns a string containing the representation of <i>fix</i> radix - * <i>base</i> (between 2 and 36). - * - * 12345.to_s #=> "12345" - * 12345.to_s(2) #=> "11000000111001" - * 12345.to_s(8) #=> "30071" - * 12345.to_s(10) #=> "12345" - * 12345.to_s(16) #=> "3039" - * 12345.to_s(36) #=> "9ix" - * - */ -static mrb_value -fix_to_s(mrb_state *mrb, mrb_value self) -{ - mrb_int base = 10; - - mrb_get_args(mrb, "|i", &base); - return mrb_fixnum_to_str(mrb, self, base); -} - -/* 15.2.9.3.6 */ -/* - * call-seq: - * self.f <=> other.f => -1, 0, +1 - * < => -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>. - */ -static mrb_value -num_cmp(mrb_state *mrb, mrb_value self) -{ - mrb_value other; - mrb_float x, y; - - mrb_get_args(mrb, "o", &other); - - x = mrb_to_flo(mrb, self); - switch (mrb_type(other)) { - case MRB_TT_FIXNUM: - y = (mrb_float)mrb_fixnum(other); - break; - case MRB_TT_FLOAT: - y = mrb_float(other); - break; - default: - return mrb_nil_value(); - } - if (x > y) - return mrb_fixnum_value(1); - else { - if (x < y) - return mrb_fixnum_value(-1); - return mrb_fixnum_value(0); - } -} - -/* 15.2.9.3.1 */ -/* - * call-seq: - * float + other -> float - * - * Returns a new float which is the sum of <code>float</code> - * and <code>other</code>. - */ -static mrb_value -flo_plus(mrb_state *mrb, mrb_value x) -{ - mrb_value y; - - mrb_get_args(mrb, "o", &y); - return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); -} - -/* ------------------------------------------------------------------------*/ -void -mrb_init_numeric(mrb_state *mrb) -{ - struct RClass *numeric, *integer, *fixnum, *fl; - - /* Numeric Class */ - numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */ - - mrb_define_method(mrb, numeric, "**", num_pow, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, numeric, "/", num_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.4 */ - mrb_define_method(mrb, numeric, "quo", num_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ - mrb_define_method(mrb, numeric, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ - - /* Integer Class */ - integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */ - MRB_SET_INSTANCE_TT(integer, MRB_TT_FIXNUM); - mrb_undef_class_method(mrb, integer, "new"); - 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()); - mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */ - mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */ - mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */ - mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */ - - /* Fixnum Class */ - mrb->fixnum_class = fixnum = 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 */ - mrb_define_method(mrb, fixnum, "*", fix_mul, MRB_ARGS_REQ(1)); /* 15.2.8.3.3 */ - mrb_define_method(mrb, fixnum, "%", fix_mod, MRB_ARGS_REQ(1)); /* 15.2.8.3.5 */ - mrb_define_method(mrb, fixnum, "==", fix_equal, MRB_ARGS_REQ(1)); /* 15.2.8.3.7 */ - mrb_define_method(mrb, fixnum, "~", fix_rev, MRB_ARGS_NONE()); /* 15.2.8.3.8 */ - mrb_define_method(mrb, fixnum, "&", fix_and, MRB_ARGS_REQ(1)); /* 15.2.8.3.9 */ - mrb_define_method(mrb, fixnum, "|", fix_or, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 */ - mrb_define_method(mrb, fixnum, "^", fix_xor, MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */ - mrb_define_method(mrb, fixnum, "<<", fix_lshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */ - mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */ - mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ - mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */ - mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */ - mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, fixnum, "divmod", fix_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ - - /* Float Class */ - mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ - MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); - mrb_undef_class_method(mrb, fl, "new"); - mrb_define_method(mrb, fl, "+", flo_plus, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */ - mrb_define_method(mrb, fl, "-", flo_minus, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */ - mrb_define_method(mrb, fl, "*", flo_mul, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */ - mrb_define_method(mrb, fl, "%", flo_mod, MRB_ARGS_REQ(1)); /* 15.2.9.3.5 */ - mrb_define_method(mrb, fl, "==", flo_eq, MRB_ARGS_REQ(1)); /* 15.2.9.3.7 */ - mrb_define_method(mrb, fl, "~", flo_rev, MRB_ARGS_NONE()); - mrb_define_method(mrb, fl, "&", flo_and, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, ">>", flo_lshift, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "<<", flo_rshift, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */ - mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ - mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_NONE()); /* 15.2.9.3.10 */ - mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, MRB_ARGS_NONE()); /* 15.2.9.3.11 */ - mrb_define_method(mrb, fl, "round", flo_round, MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */ - mrb_define_method(mrb, fl, "to_f", flo_to_f, MRB_ARGS_NONE()); /* 15.2.9.3.13 */ - mrb_define_method(mrb, fl, "to_i", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.14 */ - mrb_define_method(mrb, fl, "to_int", flo_truncate, MRB_ARGS_NONE()); - mrb_define_method(mrb, fl, "truncate", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.15 */ - mrb_define_method(mrb, fl, "divmod", flo_divmod, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "eql?", flo_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ - - mrb_define_method(mrb, fl, "to_s", flo_to_s, MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */ - mrb_define_method(mrb, fl, "inspect", flo_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, fl, "nan?", flo_nan_p, MRB_ARGS_NONE()); - -#ifdef INFINITY - mrb_define_const(mrb, fl, "INFINITY", mrb_float_value(mrb, INFINITY)); -#endif -#ifdef NAN - mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN)); -#endif -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/object.c b/web/server/h2o/libh2o/deps/mruby/src/object.c deleted file mode 100644 index 368e90b9f..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/object.c +++ /dev/null @@ -1,610 +0,0 @@ -/* -** object.c - Object, NilClass, TrueClass, FalseClass class -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/class.h> -#include <mruby/numeric.h> -#include <mruby/string.h> -#include <mruby/class.h> - -MRB_API mrb_bool -mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2) -{ - if (mrb_type(v1) != mrb_type(v2)) return FALSE; - switch (mrb_type(v1)) { - case MRB_TT_TRUE: - return TRUE; - - case MRB_TT_FALSE: - case MRB_TT_FIXNUM: - return (mrb_fixnum(v1) == mrb_fixnum(v2)); - case MRB_TT_SYMBOL: - return (mrb_symbol(v1) == mrb_symbol(v2)); - - case MRB_TT_FLOAT: - return (mrb_float(v1) == mrb_float(v2)); - - default: - return (mrb_ptr(v1) == mrb_ptr(v2)); - } -} - -MRB_API mrb_bool -mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2) -{ - /* temporary definition */ - return mrb_obj_eq(mrb, v1, v2); -} - -MRB_API mrb_bool -mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2) -{ - mrb_value result; - - if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; - result = mrb_funcall(mrb, obj1, "==", 1, obj2); - if (mrb_test(result)) return TRUE; - return FALSE; -} - -/* - * Document-class: NilClass - * - * The class of the singleton object <code>nil</code>. - */ - -/* 15.2.4.3.4 */ -/* - * call_seq: - * nil.nil? -> true - * - * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>. - */ - -static mrb_value -mrb_true(mrb_state *mrb, mrb_value obj) -{ - return mrb_true_value(); -} - -/* 15.2.4.3.5 */ -/* - * call-seq: - * nil.to_s -> "" - * - * Always returns the empty string. - */ - -static mrb_value -nil_to_s(mrb_state *mrb, mrb_value obj) -{ - return mrb_str_new(mrb, 0, 0); -} - -static mrb_value -nil_inspect(mrb_state *mrb, mrb_value obj) -{ - return mrb_str_new_lit(mrb, "nil"); -} - -/*********************************************************************** - * Document-class: TrueClass - * - * The global value <code>true</code> is the only instance of class - * <code>TrueClass</code> and represents a logically true value in - * boolean expressions. The class provides operators allowing - * <code>true</code> to be used in logical expressions. - */ - -/* 15.2.5.3.1 */ -/* - * call-seq: - * true & obj -> true or false - * - * And---Returns <code>false</code> if <i>obj</i> is - * <code>nil</code> or <code>false</code>, <code>true</code> otherwise. - */ - -static mrb_value -true_and(mrb_state *mrb, mrb_value obj) -{ - mrb_bool obj2; - - mrb_get_args(mrb, "b", &obj2); - - return mrb_bool_value(obj2); -} - -/* 15.2.5.3.2 */ -/* - * call-seq: - * true ^ obj -> !obj - * - * Exclusive Or---Returns <code>true</code> if <i>obj</i> is - * <code>nil</code> or <code>false</code>, <code>false</code> - * otherwise. - */ - -static mrb_value -true_xor(mrb_state *mrb, mrb_value obj) -{ - mrb_bool obj2; - - mrb_get_args(mrb, "b", &obj2); - return mrb_bool_value(!obj2); -} - -/* 15.2.5.3.3 */ -/* - * call-seq: - * true.to_s -> "true" - * - * The string representation of <code>true</code> is "true". - */ - -static mrb_value -true_to_s(mrb_state *mrb, mrb_value obj) -{ - return mrb_str_new_lit(mrb, "true"); -} - -/* 15.2.5.3.4 */ -/* - * call-seq: - * true | obj -> true - * - * Or---Returns <code>true</code>. As <i>anObject</i> is an argument to - * a method call, it is always evaluated; there is no short-circuit - * evaluation in this case. - * - * true | puts("or") - * true || puts("logical or") - * - * <em>produces:</em> - * - * or - */ - -static mrb_value -true_or(mrb_state *mrb, mrb_value obj) -{ - return mrb_true_value(); -} - -/* - * Document-class: FalseClass - * - * The global value <code>false</code> is the only instance of class - * <code>FalseClass</code> and represents a logically false value in - * boolean expressions. The class provides operators allowing - * <code>false</code> to participate correctly in logical expressions. - * - */ - -/* 15.2.4.3.1 */ -/* 15.2.6.3.1 */ -/* - * call-seq: - * false & obj -> false - * nil & obj -> false - * - * And---Returns <code>false</code>. <i>obj</i> is always - * evaluated as it is the argument to a method call---there is no - * short-circuit evaluation in this case. - */ - -static mrb_value -false_and(mrb_state *mrb, mrb_value obj) -{ - return mrb_false_value(); -} - -/* 15.2.4.3.2 */ -/* 15.2.6.3.2 */ -/* - * call-seq: - * false ^ obj -> true or false - * nil ^ obj -> true or false - * - * Exclusive Or---If <i>obj</i> is <code>nil</code> or - * <code>false</code>, returns <code>false</code>; otherwise, returns - * <code>true</code>. - * - */ - -static mrb_value -false_xor(mrb_state *mrb, mrb_value obj) -{ - mrb_bool obj2; - - mrb_get_args(mrb, "b", &obj2); - return mrb_bool_value(obj2); -} - -/* 15.2.4.3.3 */ -/* 15.2.6.3.4 */ -/* - * call-seq: - * false | obj -> true or false - * nil | obj -> true or false - * - * Or---Returns <code>false</code> if <i>obj</i> is - * <code>nil</code> or <code>false</code>; <code>true</code> otherwise. - */ - -static mrb_value -false_or(mrb_state *mrb, mrb_value obj) -{ - mrb_bool obj2; - - mrb_get_args(mrb, "b", &obj2); - return mrb_bool_value(obj2); -} - -/* 15.2.6.3.3 */ -/* - * call-seq: - * false.to_s -> "false" - * - * 'nuf said... - */ - -static mrb_value -false_to_s(mrb_state *mrb, mrb_value obj) -{ - return mrb_str_new_lit(mrb, "false"); -} - -void -mrb_init_object(mrb_state *mrb) -{ - struct RClass *n; - struct RClass *t; - struct RClass *f; - - mrb->nil_class = n = mrb_define_class(mrb, "NilClass", mrb->object_class); - MRB_SET_INSTANCE_TT(n, MRB_TT_TRUE); - mrb_undef_class_method(mrb, n, "new"); - mrb_define_method(mrb, n, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.4.3.1 */ - mrb_define_method(mrb, n, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.4.3.2 */ - mrb_define_method(mrb, n, "|", false_or, MRB_ARGS_REQ(1)); /* 15.2.4.3.3 */ - mrb_define_method(mrb, n, "nil?", mrb_true, MRB_ARGS_NONE()); /* 15.2.4.3.4 */ - mrb_define_method(mrb, n, "to_s", nil_to_s, MRB_ARGS_NONE()); /* 15.2.4.3.5 */ - mrb_define_method(mrb, n, "inspect", nil_inspect, MRB_ARGS_NONE()); - - mrb->true_class = t = mrb_define_class(mrb, "TrueClass", mrb->object_class); - MRB_SET_INSTANCE_TT(t, MRB_TT_TRUE); - mrb_undef_class_method(mrb, t, "new"); - mrb_define_method(mrb, t, "&", true_and, MRB_ARGS_REQ(1)); /* 15.2.5.3.1 */ - mrb_define_method(mrb, t, "^", true_xor, MRB_ARGS_REQ(1)); /* 15.2.5.3.2 */ - mrb_define_method(mrb, t, "to_s", true_to_s, MRB_ARGS_NONE()); /* 15.2.5.3.3 */ - mrb_define_method(mrb, t, "|", true_or, MRB_ARGS_REQ(1)); /* 15.2.5.3.4 */ - mrb_define_method(mrb, t, "inspect", true_to_s, MRB_ARGS_NONE()); - - mrb->false_class = f = mrb_define_class(mrb, "FalseClass", mrb->object_class); - MRB_SET_INSTANCE_TT(f, MRB_TT_TRUE); - mrb_undef_class_method(mrb, f, "new"); - mrb_define_method(mrb, f, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.6.3.1 */ - mrb_define_method(mrb, f, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.6.3.2 */ - mrb_define_method(mrb, f, "to_s", false_to_s, MRB_ARGS_NONE()); /* 15.2.6.3.3 */ - mrb_define_method(mrb, f, "|", false_or, MRB_ARGS_REQ(1)); /* 15.2.6.3.4 */ - mrb_define_method(mrb, f, "inspect", false_to_s, MRB_ARGS_NONE()); -} - -static mrb_value -inspect_type(mrb_state *mrb, mrb_value val) -{ - if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) { - return mrb_inspect(mrb, val); - } - else { - return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val)); - } -} - -static mrb_value -convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise) -{ - mrb_sym m = 0; - - m = mrb_intern_cstr(mrb, method); - if (!mrb_respond_to(mrb, val, m)) { - if (raise) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname)); - } - return mrb_nil_value(); - } - return mrb_funcall_argv(mrb, val, m, 0, 0); -} - -MRB_API mrb_value -mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method) -{ - mrb_value v; - - if (mrb_fixnum_p(val)) return val; - v = convert_type(mrb, val, "Integer", method, FALSE); - if (mrb_nil_p(v) || !mrb_fixnum_p(v)) { - return mrb_nil_value(); - } - return v; -} - -MRB_API mrb_value -mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method) -{ - mrb_value v; - - if (mrb_type(val) == type) return val; - v = convert_type(mrb, val, tname, method, TRUE); - if (mrb_type(v) != type) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val, - mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method)); - } - return v; -} - -MRB_API mrb_value -mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method) -{ - mrb_value v; - - if (mrb_type(val) == type && type != MRB_TT_DATA && type != MRB_TT_ISTRUCT) return val; - v = convert_type(mrb, val, tname, method, FALSE); - if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value(); - return v; -} - -static const struct types { - unsigned char type; - const char *name; -} builtin_types[] = { -/* {MRB_TT_NIL, "nil"}, */ - {MRB_TT_FALSE, "false"}, - {MRB_TT_TRUE, "true"}, - {MRB_TT_FIXNUM, "Fixnum"}, - {MRB_TT_SYMBOL, "Symbol"}, /* :symbol */ - {MRB_TT_MODULE, "Module"}, - {MRB_TT_OBJECT, "Object"}, - {MRB_TT_CLASS, "Class"}, - {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */ - {MRB_TT_SCLASS, "SClass"}, - {MRB_TT_PROC, "Proc"}, - {MRB_TT_FLOAT, "Float"}, - {MRB_TT_ARRAY, "Array"}, - {MRB_TT_HASH, "Hash"}, - {MRB_TT_STRING, "String"}, - {MRB_TT_RANGE, "Range"}, -/* {MRB_TT_BIGNUM, "Bignum"}, */ - {MRB_TT_FILE, "File"}, - {MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */ -/* {MRB_TT_VARMAP, "Varmap"}, */ /* internal use: dynamic variables */ -/* {MRB_TT_NODE, "Node"}, */ /* internal use: syntax tree node */ -/* {MRB_TT_UNDEF, "undef"}, */ /* internal use: #undef; should not happen */ - {MRB_TT_MAXDEFINE, 0} -}; - -MRB_API void -mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t) -{ - const struct types *type = builtin_types; - enum mrb_vtype xt; - - xt = mrb_type(x); - if ((xt != t) || (xt == MRB_TT_DATA) || (xt == MRB_TT_ISTRUCT)) { - while (type->type < MRB_TT_MAXDEFINE) { - if (type->type == t) { - const char *etype; - - if (mrb_nil_p(x)) { - etype = "nil"; - } - else if (mrb_fixnum_p(x)) { - etype = "Fixnum"; - } - else if (mrb_type(x) == MRB_TT_SYMBOL) { - etype = "Symbol"; - } - else if (mrb_immediate_p(x)) { - etype = RSTRING_PTR(mrb_obj_as_string(mrb, x)); - } - else { - etype = mrb_obj_classname(mrb, x); - } - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)", - mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name)); - } - type++; - } - mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)", - mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x))); - } -} - -/* 15.3.1.3.46 */ -/* - * call-seq: - * obj.to_s => string - * - * Returns a string representing <i>obj</i>. The default - * <code>to_s</code> prints the object's class and an encoding of the - * object id. As a special case, the top-level object that is the - * initial execution context of Ruby programs returns "main." - */ - -MRB_API mrb_value -mrb_any_to_s(mrb_state *mrb, mrb_value obj) -{ - mrb_value str = mrb_str_new_capa(mrb, 20); - const char *cname = mrb_obj_classname(mrb, obj); - - mrb_str_cat_lit(mrb, str, "#<"); - mrb_str_cat_cstr(mrb, str, cname); - mrb_str_cat_lit(mrb, str, ":"); - mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj))); - mrb_str_cat_lit(mrb, str, ">"); - - return str; -} - -/* - * call-seq: - * obj.is_a?(class) => true or false - * obj.kind_of?(class) => true or false - * - * Returns <code>true</code> if <i>class</i> is the class of - * <i>obj</i>, or if <i>class</i> is one of the superclasses of - * <i>obj</i> or modules included in <i>obj</i>. - * - * module M; end - * class A - * include M - * end - * class B < A; end - * class C < B; end - * b = B.new - * b.instance_of? A #=> false - * b.instance_of? B #=> true - * b.instance_of? C #=> false - * b.instance_of? M #=> false - * b.kind_of? A #=> true - * b.kind_of? B #=> true - * b.kind_of? C #=> false - * b.kind_of? M #=> true - */ - -MRB_API mrb_bool -mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c) -{ - struct RClass *cl = mrb_class(mrb, obj); - - switch (c->tt) { - case MRB_TT_MODULE: - case MRB_TT_CLASS: - case MRB_TT_ICLASS: - case MRB_TT_SCLASS: - break; - - default: - mrb_raise(mrb, E_TYPE_ERROR, "class or module required"); - } - - MRB_CLASS_ORIGIN(c); - while (cl) { - if (cl == c || cl->mt == c->mt) - return TRUE; - cl = cl->super; - } - return FALSE; -} - -static mrb_value -mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method) -{ - mrb_value v; - - if (mrb_fixnum_p(val)) return val; - v = convert_type(mrb, val, "Integer", method, TRUE); - if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) { - mrb_value type = inspect_type(mrb, val); - mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)", - type, type, mrb_str_new_cstr(mrb, method), inspect_type(mrb, v)); - } - return v; -} - -MRB_API mrb_value -mrb_to_int(mrb_state *mrb, mrb_value val) -{ - return mrb_to_integer(mrb, val, "to_int"); -} - -MRB_API mrb_value -mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) -{ - mrb_value tmp; - - if (mrb_nil_p(val)) { - if (base != 0) goto arg_error; - mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); - } - switch (mrb_type(val)) { - case MRB_TT_FLOAT: - if (base != 0) goto arg_error; - else { - mrb_float f = mrb_float(val); - if (FIXABLE_FLOAT(f)) { - break; - } - } - return mrb_flo_to_fixnum(mrb, val); - - case MRB_TT_FIXNUM: - if (base != 0) goto arg_error; - return val; - - case MRB_TT_STRING: - string_conv: - return mrb_str_to_inum(mrb, val, base, TRUE); - - default: - break; - } - if (base != 0) { - tmp = mrb_check_string_type(mrb, val); - if (!mrb_nil_p(tmp)) { - val = tmp; - goto string_conv; - } -arg_error: - mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); - } - tmp = convert_type(mrb, val, "Integer", "to_int", FALSE); - if (mrb_nil_p(tmp)) { - return mrb_to_integer(mrb, val, "to_i"); - } - return tmp; -} - -MRB_API mrb_value -mrb_Integer(mrb_state *mrb, mrb_value val) -{ - return mrb_convert_to_integer(mrb, val, 0); -} - -MRB_API mrb_value -mrb_Float(mrb_state *mrb, mrb_value val) -{ - if (mrb_nil_p(val)) { - mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float"); - } - switch (mrb_type(val)) { - case MRB_TT_FIXNUM: - return mrb_float_value(mrb, (mrb_float)mrb_fixnum(val)); - - case MRB_TT_FLOAT: - return val; - - case MRB_TT_STRING: - return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE)); - - default: - return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f"); - } -} - -MRB_API mrb_value -mrb_inspect(mrb_state *mrb, mrb_value obj) -{ - return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0)); -} - -MRB_API mrb_bool -mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2) -{ - if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; - return mrb_test(mrb_funcall(mrb, obj1, "eql?", 1, obj2)); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/opcode.h b/web/server/h2o/libh2o/deps/mruby/src/opcode.h deleted file mode 100644 index fe4d17a21..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/opcode.h +++ /dev/null @@ -1,2 +0,0 @@ -/* this header file is to be removed soon. */ -#include <mruby/opcode.h> diff --git a/web/server/h2o/libh2o/deps/mruby/src/pool.c b/web/server/h2o/libh2o/deps/mruby/src/pool.c deleted file mode 100644 index db4546abf..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/pool.c +++ /dev/null @@ -1,198 +0,0 @@ -/* -** pool.c - memory pool -** -** See Copyright Notice in mruby.h -*/ - -#include <stddef.h> -#include <stdint.h> -#include <string.h> -#include <mruby.h> - -/* configuration section */ -/* allocated memory address should be multiple of POOL_ALIGNMENT */ -/* or undef it if alignment does not matter */ -#ifndef POOL_ALIGNMENT -#if INTPTR_MAX == INT64_MAX -#define POOL_ALIGNMENT 8 -#else -#define POOL_ALIGNMENT 4 -#endif -#endif -/* page size of memory pool */ -#ifndef POOL_PAGE_SIZE -#define POOL_PAGE_SIZE 16000 -#endif -/* end of configuration section */ - -struct mrb_pool_page { - struct mrb_pool_page *next; - size_t offset; - size_t len; - void *last; - char page[]; -}; - -struct mrb_pool { - mrb_state *mrb; - struct mrb_pool_page *pages; -}; - -#undef TEST_POOL -#ifdef TEST_POOL - -#define mrb_malloc_simple(m,s) malloc(s) -#define mrb_free(m,p) free(p) -#endif - -#ifdef POOL_ALIGNMENT -# define ALIGN_PADDING(x) ((SIZE_MAX - (x) + 1) & (POOL_ALIGNMENT - 1)) -#else -# define ALIGN_PADDING(x) (0) -#endif - -MRB_API mrb_pool* -mrb_pool_open(mrb_state *mrb) -{ - mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool)); - - if (pool) { - pool->mrb = mrb; - pool->pages = NULL; - } - - return pool; -} - -MRB_API void -mrb_pool_close(mrb_pool *pool) -{ - struct mrb_pool_page *page, *tmp; - - if (!pool) return; - page = pool->pages; - while (page) { - tmp = page; - page = page->next; - mrb_free(pool->mrb, tmp); - } - mrb_free(pool->mrb, pool); -} - -static struct mrb_pool_page* -page_alloc(mrb_pool *pool, size_t len) -{ - struct mrb_pool_page *page; - - if (len < POOL_PAGE_SIZE) - len = POOL_PAGE_SIZE; - page = (struct mrb_pool_page *)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len); - if (page) { - page->offset = 0; - page->len = len; - } - - return page; -} - -MRB_API void* -mrb_pool_alloc(mrb_pool *pool, size_t len) -{ - struct mrb_pool_page *page; - size_t n; - - if (!pool) return NULL; - len += ALIGN_PADDING(len); - page = pool->pages; - while (page) { - if (page->offset + len <= page->len) { - n = page->offset; - page->offset += len; - page->last = (char*)page->page+n; - return page->last; - } - page = page->next; - } - page = page_alloc(pool, len); - if (!page) return NULL; - page->offset = len; - page->next = pool->pages; - pool->pages = page; - - page->last = (void*)page->page; - return page->last; -} - -MRB_API mrb_bool -mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len) -{ - struct mrb_pool_page *page; - - if (!pool) return FALSE; - len += ALIGN_PADDING(len); - page = pool->pages; - while (page) { - if (page->last == p) { - size_t beg; - - beg = (char*)p - page->page; - if (beg + len > page->len) return FALSE; - return TRUE; - } - page = page->next; - } - return FALSE; -} - -MRB_API void* -mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen) -{ - struct mrb_pool_page *page; - void *np; - - if (!pool) return NULL; - oldlen += ALIGN_PADDING(oldlen); - newlen += ALIGN_PADDING(newlen); - page = pool->pages; - while (page) { - if (page->last == p) { - size_t beg; - - beg = (char*)p - page->page; - if (beg + oldlen != page->offset) break; - if (beg + newlen > page->len) { - page->offset = beg; - break; - } - page->offset = beg + newlen; - return p; - } - page = page->next; - } - np = mrb_pool_alloc(pool, newlen); - if (np == NULL) { - return NULL; - } - memcpy(np, p, oldlen); - return np; -} - -#ifdef TEST_POOL -int -main(void) -{ - int i, len = 250; - mrb_pool *pool; - void *p; - - pool = mrb_pool_open(NULL); - p = mrb_pool_alloc(pool, len); - for (i=1; i<20; i++) { - printf("%p (len=%d) %ud\n", p, len, mrb_pool_can_realloc(pool, p, len*2)); - p = mrb_pool_realloc(pool, p, len, len*2); - len *= 2; - } - mrb_pool_close(pool); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/mruby/src/print.c b/web/server/h2o/libh2o/deps/mruby/src/print.c deleted file mode 100644 index 03b5eadfa..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/print.c +++ /dev/null @@ -1,47 +0,0 @@ -/* -** print.c - Kernel.#p -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/string.h> -#include <mruby/variable.h> - -#ifndef MRB_DISABLE_STDIO -static void -printstr(mrb_value obj, FILE *stream) -{ - if (mrb_string_p(obj)) { - fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stream); - putc('\n', stream); - } -} -#else -# define printstr(obj, stream) (void)0 -#endif - -MRB_API void -mrb_p(mrb_state *mrb, mrb_value obj) -{ - printstr(mrb_inspect(mrb, obj), stdout); -} - -MRB_API void -mrb_print_error(mrb_state *mrb) -{ - mrb_print_backtrace(mrb); - printstr(mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0), stderr); -} - -MRB_API void -mrb_show_version(mrb_state *mrb) -{ - printstr(mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_DESCRIPTION")), stdout); -} - -MRB_API void -mrb_show_copyright(mrb_state *mrb) -{ - printstr(mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_COPYRIGHT")), stdout); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/proc.c b/web/server/h2o/libh2o/deps/mruby/src/proc.c deleted file mode 100644 index 10a2c4f33..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/proc.c +++ /dev/null @@ -1,294 +0,0 @@ -/* -** proc.c - Proc class -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/class.h> -#include <mruby/proc.h> -#include <mruby/opcode.h> - -static mrb_code call_iseq[] = { - MKOP_A(OP_CALL, 0), -}; - -struct RProc* -mrb_proc_new(mrb_state *mrb, mrb_irep *irep) -{ - struct RProc *p; - mrb_callinfo *ci = mrb->c->ci; - - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); - p->target_class = 0; - if (ci) { - if (ci->proc) - p->target_class = ci->proc->target_class; - if (!p->target_class) - p->target_class = ci->target_class; - } - p->body.irep = irep; - p->env = 0; - mrb_irep_incref(mrb, irep); - - return p; -} - -static struct REnv* -env_new(mrb_state *mrb, int nlocals) -{ - struct REnv *e; - - e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env); - MRB_SET_ENV_STACK_LEN(e, nlocals); - e->cxt.c = mrb->c; - e->cioff = mrb->c->ci - mrb->c->cibase; - e->stack = mrb->c->stack; - - return e; -} - -static void -closure_setup(mrb_state *mrb, struct RProc *p, int nlocals) -{ - struct REnv *e; - - if (!mrb->c->ci->env) { - e = env_new(mrb, nlocals); - mrb->c->ci->env = e; - } - else { - e = mrb->c->ci->env; - } - p->env = e; - mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env); -} - -struct RProc* -mrb_closure_new(mrb_state *mrb, mrb_irep *irep) -{ - struct RProc *p = mrb_proc_new(mrb, irep); - - closure_setup(mrb, p, mrb->c->ci->proc->body.irep->nlocals); - return p; -} - -MRB_API struct RProc* -mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) -{ - struct RProc *p; - - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); - p->body.func = func; - p->flags |= MRB_PROC_CFUNC; - p->env = 0; - - return p; -} - -MRB_API struct RProc* -mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv) -{ - struct RProc *p = mrb_proc_new_cfunc(mrb, func); - struct REnv *e; - int i; - - p->env = e = env_new(mrb, argc); - mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env); - MRB_ENV_UNSHARE_STACK(e); - e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); - if (argv) { - for (i = 0; i < argc; ++i) { - e->stack[i] = argv[i]; - } - } - else { - for (i = 0; i < argc; ++i) { - SET_NIL_VALUE(e->stack[i]); - } - } - return p; -} - -MRB_API struct RProc* -mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals) -{ - return mrb_proc_new_cfunc_with_env(mrb, func, nlocals, NULL); -} - -MRB_API mrb_value -mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx) -{ - struct RProc *p = mrb->c->ci->proc; - struct REnv *e = p->env; - - if (!MRB_PROC_CFUNC_P(p)) { - mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc."); - } - if (!e) { - mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); - } - if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) { - mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)", - mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e))); - } - - return e->stack[idx]; -} - -void -mrb_proc_copy(struct RProc *a, struct RProc *b) -{ - if (a->body.irep) { - /* already initialized proc */ - return; - } - a->flags = b->flags; - a->body = b->body; - if (!MRB_PROC_CFUNC_P(a) && a->body.irep) { - a->body.irep->refcnt++; - } - a->target_class = b->target_class; - a->env = b->env; -} - -static mrb_value -mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) -{ - mrb_value blk; - mrb_value proc; - struct RProc *p; - - mrb_get_args(mrb, "&", &blk); - if (mrb_nil_p(blk)) { - /* Calling Proc.new without a block is not implemented yet */ - mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); - } - p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class)); - mrb_proc_copy(p, mrb_proc_ptr(blk)); - proc = mrb_obj_value(p); - mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, proc); - if (!MRB_PROC_STRICT_P(p) && - mrb->c->ci > mrb->c->cibase && p->env == mrb->c->ci[-1].env) { - p->flags |= MRB_PROC_ORPHAN; - } - return proc; -} - -static mrb_value -mrb_proc_init_copy(mrb_state *mrb, mrb_value self) -{ - mrb_value proc; - - mrb_get_args(mrb, "o", &proc); - if (mrb_type(proc) != MRB_TT_PROC) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); - } - mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc)); - return self; -} - -int -mrb_proc_cfunc_p(struct RProc *p) -{ - return MRB_PROC_CFUNC_P(p); -} - -mrb_value -mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self) -{ - return (p->body.func)(mrb, self); -} - -/* 15.2.17.4.2 */ -static mrb_value -mrb_proc_arity(mrb_state *mrb, mrb_value self) -{ - struct RProc *p = mrb_proc_ptr(self); - struct mrb_irep *irep; - mrb_code *iseq; - mrb_aspec aspec; - int ma, op, ra, pa, arity; - - if (MRB_PROC_CFUNC_P(p)) { - /* TODO cfunc aspec not implemented yet */ - return mrb_fixnum_value(-1); - } - - irep = p->body.irep; - if (!irep) { - return mrb_fixnum_value(0); - } - - iseq = irep->iseq; - /* arity is depend on OP_ENTER */ - if (GET_OPCODE(*iseq) != OP_ENTER) { - return mrb_fixnum_value(0); - } - - aspec = GETARG_Ax(*iseq); - ma = MRB_ASPEC_REQ(aspec); - op = MRB_ASPEC_OPT(aspec); - ra = MRB_ASPEC_REST(aspec); - pa = MRB_ASPEC_POST(aspec); - arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa; - - return mrb_fixnum_value(arity); -} - -/* 15.3.1.2.6 */ -/* 15.3.1.3.27 */ -/* - * call-seq: - * lambda { |...| block } -> a_proc - * - * Equivalent to <code>Proc.new</code>, except the resulting Proc objects - * check the number of parameters passed when called. - */ -static mrb_value -proc_lambda(mrb_state *mrb, mrb_value self) -{ - mrb_value blk; - struct RProc *p; - - mrb_get_args(mrb, "&", &blk); - if (mrb_nil_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); - } - if (mrb_type(blk) != MRB_TT_PROC) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); - } - p = mrb_proc_ptr(blk); - if (!MRB_PROC_STRICT_P(p)) { - struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c); - mrb_proc_copy(p2, p); - p2->flags |= MRB_PROC_STRICT; - return mrb_obj_value(p2); - } - return blk; -} - -void -mrb_init_proc(mrb_state *mrb) -{ - struct RProc *m; - mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); - static const mrb_irep mrb_irep_zero = { 0 }; - - *call_irep = mrb_irep_zero; - call_irep->flags = MRB_ISEQ_NO_FREE; - call_irep->iseq = call_iseq; - call_irep->ilen = 1; - call_irep->nregs = 2; /* receiver and block */ - - mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_ANY()); - mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE()); - - m = mrb_proc_new(mrb, call_irep); - mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "call"), m); - mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "[]"), m); - - mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.2.6 */ - mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.3.27 */ -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/range.c b/web/server/h2o/libh2o/deps/mruby/src/range.c deleted file mode 100644 index eb9a9c61f..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/range.c +++ /dev/null @@ -1,442 +0,0 @@ -/* -** range.c - Range class -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/class.h> -#include <mruby/range.h> -#include <mruby/string.h> -#include <mruby/array.h> - -MRB_API struct RRange* -mrb_range_ptr(mrb_state *mrb, mrb_value v) -{ - struct RRange *r = (struct RRange*)mrb_ptr(v); - - if (r->edges == NULL) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range"); - } - return r; -} - -static void -range_check(mrb_state *mrb, mrb_value a, mrb_value b) -{ - mrb_value ans; - enum mrb_vtype ta; - enum mrb_vtype tb; - - ta = mrb_type(a); - tb = mrb_type(b); - if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) && - (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) { - return; - } - - ans = mrb_funcall(mrb, a, "<=>", 1, b); - if (mrb_nil_p(ans)) { - /* can not be compared */ - mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range"); - } -} - -MRB_API mrb_value -mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) -{ - struct RRange *r; - - range_check(mrb, beg, end); - r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class); - r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); - r->edges->beg = beg; - r->edges->end = end; - r->excl = excl; - return mrb_range_value(r); -} - -/* - * call-seq: - * rng.first => obj - * rng.begin => obj - * - * Returns the first object in <i>rng</i>. - */ -mrb_value -mrb_range_beg(mrb_state *mrb, mrb_value range) -{ - struct RRange *r = mrb_range_ptr(mrb, range); - - return r->edges->beg; -} - -/* - * call-seq: - * rng.end => obj - * rng.last => obj - * - * Returns the object that defines the end of <i>rng</i>. - * - * (1..10).end #=> 10 - * (1...10).end #=> 10 - */ - -mrb_value -mrb_range_end(mrb_state *mrb, mrb_value range) -{ - struct RRange *r = mrb_range_ptr(mrb, range); - - return r->edges->end; -} - -/* - * call-seq: - * range.exclude_end? => true or false - * - * Returns <code>true</code> if <i>range</i> excludes its end value. - */ -mrb_value -mrb_range_excl(mrb_state *mrb, mrb_value range) -{ - struct RRange *r = mrb_range_ptr(mrb, range); - - return mrb_bool_value(r->excl); -} - -static void -range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end) -{ - struct RRange *r = mrb_range_raw_ptr(range); - - range_check(mrb, beg, end); - r->excl = exclude_end; - if (!r->edges) { - r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); - } - r->edges->beg = beg; - r->edges->end = end; -} -/* - * call-seq: - * Range.new(start, end, exclusive=false) => range - * - * Constructs a range using the given <i>start</i> and <i>end</i>. If the third - * parameter is omitted or is <code>false</code>, the <i>range</i> will include - * the end object; otherwise, it will be excluded. - */ - -mrb_value -mrb_range_initialize(mrb_state *mrb, mrb_value range) -{ - mrb_value beg, end; - mrb_bool exclusive; - int n; - - n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive); - if (n != 3) { - exclusive = FALSE; - } - /* Ranges are immutable, so that they should be initialized only once. */ - if (mrb_range_raw_ptr(range)->edges) { - mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice"); - } - range_init(mrb, range, beg, end, exclusive); - return range; -} -/* - * call-seq: - * range == obj => true or false - * - * Returns <code>true</code> only if - * 1) <i>obj</i> is a Range, - * 2) <i>obj</i> has equivalent beginning and end items (by comparing them with <code>==</code>), - * 3) <i>obj</i> has the same #exclude_end? setting as <i>rng</t>. - * - * (0..2) == (0..2) #=> true - * (0..2) == Range.new(0,2) #=> true - * (0..2) == (0...2) #=> false - * - */ - -mrb_value -mrb_range_eq(mrb_state *mrb, mrb_value range) -{ - struct RRange *rr; - struct RRange *ro; - mrb_value obj, v1, v2; - - mrb_get_args(mrb, "o", &obj); - - if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); - if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */ - return mrb_false_value(); - } - - rr = mrb_range_ptr(mrb, range); - ro = mrb_range_ptr(mrb, obj); - v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg); - v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end); - if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) { - return mrb_false_value(); - } - return mrb_true_value(); -} - -static mrb_bool -r_le(mrb_state *mrb, mrb_value a, mrb_value b) -{ - mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */ - /* output :a < b => -1, a = b => 0, a > b => +1 */ - - if (mrb_fixnum_p(r)) { - mrb_int c = mrb_fixnum(r); - if (c == 0 || c == -1) return TRUE; - } - - return FALSE; -} - -static mrb_bool -r_gt(mrb_state *mrb, mrb_value a, mrb_value b) -{ - mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); - /* output :a < b => -1, a = b => 0, a > b => +1 */ - - return mrb_fixnum_p(r) && mrb_fixnum(r) == 1; -} - -static mrb_bool -r_ge(mrb_state *mrb, mrb_value a, mrb_value b) -{ - mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */ - /* output :a < b => -1, a = b => 0, a > b => +1 */ - - if (mrb_fixnum_p(r)) { - mrb_int c = mrb_fixnum(r); - if (c == 0 || c == 1) return TRUE; - } - - return FALSE; -} - -/* - * call-seq: - * range === obj => true or false - * range.member?(val) => true or false - * range.include?(val) => true or false - * - */ -mrb_value -mrb_range_include(mrb_state *mrb, mrb_value range) -{ - mrb_value val; - struct RRange *r = mrb_range_ptr(mrb, range); - mrb_value beg, end; - mrb_bool include_p; - - mrb_get_args(mrb, "o", &val); - - beg = r->edges->beg; - end = r->edges->end; - include_p = r_le(mrb, beg, val) && /* beg <= val */ - (r->excl ? r_gt(mrb, end, val) /* end > val */ - : r_ge(mrb, end, val)); /* end >= val */ - - return mrb_bool_value(include_p); -} - -MRB_API mrb_int -mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc) -{ - mrb_int beg, end; - struct RRange *r; - - if (mrb_type(range) != MRB_TT_RANGE) return 0; - r = mrb_range_ptr(mrb, range); - - beg = mrb_int(mrb, r->edges->beg); - end = mrb_int(mrb, r->edges->end); - - if (beg < 0) { - beg += len; - if (beg < 0) return 2; - } - - if (trunc) { - if (beg > len) return 2; - if (end > len) end = len; - } - - if (end < 0) end += len; - if (!r->excl && (!trunc || end < len)) - end++; /* include end point */ - len = end - beg; - if (len < 0) len = 0; - - *begp = beg; - *lenp = len; - return 1; -} - -/* 15.2.14.4.12(x) */ -/* - * call-seq: - * rng.to_s -> string - * - * Convert this range object to a printable form. - */ - -static mrb_value -range_to_s(mrb_state *mrb, mrb_value range) -{ - mrb_value str, str2; - struct RRange *r = mrb_range_ptr(mrb, range); - - str = mrb_obj_as_string(mrb, r->edges->beg); - str2 = mrb_obj_as_string(mrb, r->edges->end); - str = mrb_str_dup(mrb, str); - mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); - mrb_str_cat_str(mrb, str, str2); - - return str; -} - -/* 15.2.14.4.13(x) */ -/* - * call-seq: - * rng.inspect -> string - * - * Convert this range object to a printable form (using - * <code>inspect</code> to convert the start and end - * objects). - */ - -static mrb_value -range_inspect(mrb_state *mrb, mrb_value range) -{ - mrb_value str, str2; - struct RRange *r = mrb_range_ptr(mrb, range); - - str = mrb_inspect(mrb, r->edges->beg); - str2 = mrb_inspect(mrb, r->edges->end); - str = mrb_str_dup(mrb, str); - mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); - mrb_str_cat_str(mrb, str, str2); - - return str; -} - -/* 15.2.14.4.14(x) */ -/* - * call-seq: - * rng.eql?(obj) -> true or false - * - * Returns <code>true</code> only if <i>obj</i> is a Range, has equivalent - * beginning and end items (by comparing them with #eql?), and has the same - * #exclude_end? setting as <i>rng</i>. - * - * (0..2).eql?(0..2) #=> true - * (0..2).eql?(Range.new(0,2)) #=> true - * (0..2).eql?(0...2) #=> false - * - */ - -static mrb_value -range_eql(mrb_state *mrb, mrb_value range) -{ - mrb_value obj; - struct RRange *r, *o; - - mrb_get_args(mrb, "o", &obj); - - if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); - if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) { - return mrb_false_value(); - } - if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value(); - - r = mrb_range_ptr(mrb, range); - o = mrb_range_ptr(mrb, obj); - if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) || - !mrb_eql(mrb, r->edges->end, o->edges->end) || - (r->excl != o->excl)) { - return mrb_false_value(); - } - return mrb_true_value(); -} - -/* 15.2.14.4.15(x) */ -static mrb_value -range_initialize_copy(mrb_state *mrb, mrb_value copy) -{ - mrb_value src; - struct RRange *r; - - mrb_get_args(mrb, "o", &src); - - if (mrb_obj_equal(mrb, copy, src)) return copy; - if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { - mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); - } - - r = mrb_range_ptr(mrb, src); - range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl); - - return copy; -} - -mrb_value -mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)) -{ - mrb_int i, j, beg, len; - mrb_value result; - result = mrb_ary_new(mrb); - - for (i = 0; i < argc; ++i) { - if (mrb_fixnum_p(argv[i])) { - mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i]))); - } - else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) { - mrb_int const end = olen < beg + len ? olen : beg + len; - for (j = beg; j < end; ++j) { - mrb_ary_push(mrb, result, func(mrb, obj, j)); - } - - for (; j < beg + len; ++j) { - mrb_ary_push(mrb, result, mrb_nil_value()); - } - } - else { - mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %S", argv[i]); - } - } - - return result; -} - -void -mrb_init_range(mrb_state *mrb) -{ - struct RClass *r; - - r = mrb_define_class(mrb, "Range", mrb->object_class); /* 15.2.14 */ - mrb->range_class = r; - MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE); - - mrb_define_method(mrb, r, "begin", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */ - mrb_define_method(mrb, r, "end", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */ - mrb_define_method(mrb, r, "==", mrb_range_eq, MRB_ARGS_REQ(1)); /* 15.2.14.4.1 */ - mrb_define_method(mrb, r, "===", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.2 */ - mrb_define_method(mrb, r, "exclude_end?", mrb_range_excl, MRB_ARGS_NONE()); /* 15.2.14.4.6 */ - mrb_define_method(mrb, r, "first", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */ - mrb_define_method(mrb, r, "include?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.8 */ - mrb_define_method(mrb, r, "initialize", mrb_range_initialize, MRB_ARGS_ANY()); /* 15.2.14.4.9 */ - mrb_define_method(mrb, r, "last", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */ - mrb_define_method(mrb, r, "member?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */ - - mrb_define_method(mrb, r, "to_s", range_to_s, MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */ - mrb_define_method(mrb, r, "inspect", range_inspect, MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */ - mrb_define_method(mrb, r, "eql?", range_eql, MRB_ARGS_REQ(1)); /* 15.2.14.4.14(x) */ - mrb_define_method(mrb, r, "initialize_copy", range_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.14.4.15(x) */ -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/state.c b/web/server/h2o/libh2o/deps/mruby/src/state.c deleted file mode 100644 index 039d67d57..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/state.c +++ /dev/null @@ -1,303 +0,0 @@ -/* -** state.c - mrb_state open/close functions -** -** See Copyright Notice in mruby.h -*/ - -#include <stdlib.h> -#include <string.h> -#include <mruby.h> -#include <mruby/irep.h> -#include <mruby/variable.h> -#include <mruby/debug.h> -#include <mruby/string.h> - -void mrb_init_core(mrb_state*); -void mrb_init_mrbgems(mrb_state*); - -void mrb_gc_init(mrb_state*, mrb_gc *gc); -void mrb_gc_destroy(mrb_state*, mrb_gc *gc); - -static mrb_value -inspect_main(mrb_state *mrb, mrb_value mod) -{ - return mrb_str_new_lit(mrb, "main"); -} - -MRB_API mrb_state* -mrb_open_core(mrb_allocf f, void *ud) -{ - static const mrb_state mrb_state_zero = { 0 }; - static const struct mrb_context mrb_context_zero = { 0 }; - mrb_state *mrb; - - mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); - if (mrb == NULL) return NULL; - - *mrb = mrb_state_zero; - mrb->allocf_ud = ud; - mrb->allocf = f; - mrb->atexit_stack_len = 0; - - mrb_gc_init(mrb, &mrb->gc); - mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context)); - *mrb->c = mrb_context_zero; - mrb->root_c = mrb->c; - - mrb_init_core(mrb); - - return mrb; -} - -void* -mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud) -{ - if (size == 0) { - free(p); - return NULL; - } - else { - return realloc(p, size); - } -} - -struct alloca_header { - struct alloca_header *next; - char buf[]; -}; - -MRB_API void* -mrb_alloca(mrb_state *mrb, size_t size) -{ - struct alloca_header *p; - - p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size); - p->next = mrb->mems; - mrb->mems = p; - return (void*)p->buf; -} - -static void -mrb_alloca_free(mrb_state *mrb) -{ - struct alloca_header *p; - struct alloca_header *tmp; - - if (mrb == NULL) return; - p = mrb->mems; - - while (p) { - tmp = p; - p = p->next; - mrb_free(mrb, tmp); - } -} - -MRB_API mrb_state* -mrb_open(void) -{ - mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL); - - return mrb; -} - -MRB_API mrb_state* -mrb_open_allocf(mrb_allocf f, void *ud) -{ - mrb_state *mrb = mrb_open_core(f, ud); - - if (mrb == NULL) { - return NULL; - } - -#ifndef DISABLE_GEMS - mrb_init_mrbgems(mrb); - mrb_gc_arena_restore(mrb, 0); -#endif - return mrb; -} - -void mrb_free_symtbl(mrb_state *mrb); - -void -mrb_irep_incref(mrb_state *mrb, mrb_irep *irep) -{ - irep->refcnt++; -} - -void -mrb_irep_decref(mrb_state *mrb, mrb_irep *irep) -{ - irep->refcnt--; - if (irep->refcnt == 0) { - mrb_irep_free(mrb, irep); - } -} - -void -mrb_irep_free(mrb_state *mrb, mrb_irep *irep) -{ - int i; - - if (!(irep->flags & MRB_ISEQ_NO_FREE)) - mrb_free(mrb, irep->iseq); - if (irep->pool) for (i=0; i<irep->plen; i++) { - if (mrb_type(irep->pool[i]) == MRB_TT_STRING) { - mrb_gc_free_str(mrb, RSTRING(irep->pool[i])); - mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); - } -#ifdef MRB_WORD_BOXING - else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { - mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); - } -#endif - } - mrb_free(mrb, irep->pool); - mrb_free(mrb, irep->syms); - for (i=0; i<irep->rlen; i++) { - mrb_irep_decref(mrb, irep->reps[i]); - } - if (irep->outer) - mrb_irep_decref(mrb, irep->outer); - mrb_free(mrb, irep->reps); - mrb_free(mrb, irep->lv); - if (irep->own_filename) { - mrb_free(mrb, (void *)irep->filename); - } - mrb_free(mrb, irep->lines); - mrb_debug_info_free(mrb, irep->debug_info); - mrb_free(mrb, irep); -} - -mrb_value -mrb_str_pool(mrb_state *mrb, mrb_value str) -{ - struct RString *s = mrb_str_ptr(str); - struct RString *ns; - char *ptr; - mrb_int len; - - ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString)); - ns->tt = MRB_TT_STRING; - ns->c = mrb->string_class; - - if (RSTR_NOFREE_P(s)) { - ns->flags = MRB_STR_NOFREE; - ns->as.heap.ptr = s->as.heap.ptr; - ns->as.heap.len = s->as.heap.len; - ns->as.heap.aux.capa = 0; - } - else { - ns->flags = 0; - if (RSTR_EMBED_P(s)) { - ptr = s->as.ary; - len = RSTR_EMBED_LEN(s); - } - else { - ptr = s->as.heap.ptr; - len = s->as.heap.len; - } - - if (len < RSTRING_EMBED_LEN_MAX) { - RSTR_SET_EMBED_FLAG(ns); - RSTR_SET_EMBED_LEN(ns, len); - if (ptr) { - memcpy(ns->as.ary, ptr, len); - } - ns->as.ary[len] = '\0'; - } - else { - ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); - ns->as.heap.len = len; - ns->as.heap.aux.capa = len; - if (ptr) { - memcpy(ns->as.heap.ptr, ptr, len); - } - ns->as.heap.ptr[len] = '\0'; - } - } - return mrb_obj_value(ns); -} - -void mrb_free_backtrace(mrb_state *mrb); - -MRB_API void -mrb_free_context(mrb_state *mrb, struct mrb_context *c) -{ - if (!c) return; - mrb_free(mrb, c->stbase); - mrb_free(mrb, c->cibase); - mrb_free(mrb, c->rescue); - mrb_free(mrb, c->ensure); - mrb_free(mrb, c); -} - -MRB_API void -mrb_close(mrb_state *mrb) -{ - if (!mrb) return; - if (mrb->atexit_stack_len > 0) { - mrb_int i; - for (i = mrb->atexit_stack_len; i > 0; --i) { - mrb->atexit_stack[i - 1](mrb); - } -#ifndef MRB_FIXED_STATE_ATEXIT_STACK - mrb_free(mrb, mrb->atexit_stack); -#endif - } - - /* free */ - mrb_gc_free_gv(mrb); - mrb_free_context(mrb, mrb->root_c); - mrb_free_symtbl(mrb); - mrb_alloca_free(mrb); - mrb_gc_destroy(mrb, &mrb->gc); - mrb_free(mrb, mrb); -} - -MRB_API mrb_irep* -mrb_add_irep(mrb_state *mrb) -{ - static const mrb_irep mrb_irep_zero = { 0 }; - mrb_irep *irep; - - irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); - *irep = mrb_irep_zero; - irep->refcnt = 1; - irep->own_filename = FALSE; - - return irep; -} - -MRB_API mrb_value -mrb_top_self(mrb_state *mrb) -{ - if (!mrb->top_self) { - mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class); - mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE()); - mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE()); - } - return mrb_obj_value(mrb->top_self); -} - -MRB_API void -mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f) -{ -#ifdef MRB_FIXED_STATE_ATEXIT_STACK - if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) { - mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit"); - } -#else - size_t stack_size; - - stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1); - if (mrb->atexit_stack_len == 0) { - mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size); - } - else { - mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size); - } -#endif - - mrb->atexit_stack[mrb->atexit_stack_len++] = f; -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/string.c b/web/server/h2o/libh2o/deps/mruby/src/string.c deleted file mode 100644 index 01d706fa3..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/string.c +++ /dev/null @@ -1,3013 +0,0 @@ -/* -** string.c - String class -** -** See Copyright Notice in mruby.h -*/ - -#ifdef _MSC_VER -# define _CRT_NONSTDC_NO_DEPRECATE -#endif - -#include <float.h> -#include <limits.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/range.h> -#include <mruby/string.h> -#include <mruby/re.h> - -typedef struct mrb_shared_string { - mrb_bool nofree : 1; - int refcnt; - char *ptr; - mrb_int len; -} mrb_shared_string; - -const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - -#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class)) - -static struct RString* -str_new_static(mrb_state *mrb, const char *p, size_t len) -{ - struct RString *s; - - if (len >= MRB_INT_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } - s = mrb_obj_alloc_string(mrb); - s->as.heap.len = (mrb_int)len; - s->as.heap.aux.capa = 0; /* nofree */ - s->as.heap.ptr = (char *)p; - s->flags = MRB_STR_NOFREE; - - return s; -} - -static struct RString* -str_new(mrb_state *mrb, const char *p, size_t len) -{ - struct RString *s; - - if (p && mrb_ro_data_p(p)) { - return str_new_static(mrb, p, len); - } - s = mrb_obj_alloc_string(mrb); - if (len < RSTRING_EMBED_LEN_MAX) { - RSTR_SET_EMBED_FLAG(s); - RSTR_SET_EMBED_LEN(s, len); - if (p) { - memcpy(s->as.ary, p, len); - } - } - else { - if (len >= MRB_INT_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } - s->as.heap.len = (mrb_int)len; - s->as.heap.aux.capa = (mrb_int)len; - s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1); - if (p) { - memcpy(s->as.heap.ptr, p, len); - } - } - RSTR_PTR(s)[len] = '\0'; - return s; -} - -static inline void -str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj) -{ - s->c = mrb_str_ptr(obj)->c; -} - -static mrb_value -mrb_str_new_empty(mrb_state *mrb, mrb_value str) -{ - struct RString *s = str_new(mrb, 0, 0); - - str_with_class(mrb, s, str); - return mrb_obj_value(s); -} - -MRB_API mrb_value -mrb_str_new_capa(mrb_state *mrb, size_t capa) -{ - struct RString *s; - - s = mrb_obj_alloc_string(mrb); - - if (capa >= MRB_INT_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); - } - s->as.heap.len = 0; - s->as.heap.aux.capa = (mrb_int)capa; - s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1); - RSTR_PTR(s)[0] = '\0'; - - return mrb_obj_value(s); -} - -#ifndef MRB_STR_BUF_MIN_SIZE -# define MRB_STR_BUF_MIN_SIZE 128 -#endif - -MRB_API mrb_value -mrb_str_buf_new(mrb_state *mrb, size_t capa) -{ - if (capa < MRB_STR_BUF_MIN_SIZE) { - capa = MRB_STR_BUF_MIN_SIZE; - } - return mrb_str_new_capa(mrb, capa); -} - -static void -resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) -{ -#if SIZE_MAX > MRB_INT_MAX - mrb_assert(capacity < MRB_INT_MAX); -#endif - if (RSTR_EMBED_P(s)) { - if (RSTRING_EMBED_LEN_MAX < capacity) { - char *const tmp = (char *)mrb_malloc(mrb, capacity+1); - const mrb_int len = RSTR_EMBED_LEN(s); - memcpy(tmp, s->as.ary, len); - RSTR_UNSET_EMBED_FLAG(s); - s->as.heap.ptr = tmp; - s->as.heap.len = len; - s->as.heap.aux.capa = (mrb_int)capacity; - } - } - else { - s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); - s->as.heap.aux.capa = (mrb_int)capacity; - } -} - -MRB_API mrb_value -mrb_str_new(mrb_state *mrb, const char *p, size_t len) -{ - return mrb_obj_value(str_new(mrb, p, len)); -} - -/* - * call-seq: (Caution! NULL string) - * String.new(str="") => new_str - * - * Returns a new string object containing a copy of <i>str</i>. - */ - -MRB_API mrb_value -mrb_str_new_cstr(mrb_state *mrb, const char *p) -{ - struct RString *s; - size_t len; - - if (p) { - len = strlen(p); - } - else { - len = 0; - } - - s = str_new(mrb, p, len); - - return mrb_obj_value(s); -} - -MRB_API mrb_value -mrb_str_new_static(mrb_state *mrb, const char *p, size_t len) -{ - struct RString *s = str_new_static(mrb, p, len); - return mrb_obj_value(s); -} - -static void -str_decref(mrb_state *mrb, mrb_shared_string *shared) -{ - shared->refcnt--; - if (shared->refcnt == 0) { - if (!shared->nofree) { - mrb_free(mrb, shared->ptr); - } - mrb_free(mrb, shared); - } -} - -void -mrb_gc_free_str(mrb_state *mrb, struct RString *str) -{ - if (RSTR_EMBED_P(str)) - /* no code */; - else if (RSTR_SHARED_P(str)) - str_decref(mrb, str->as.heap.aux.shared); - else if (!RSTR_NOFREE_P(str)) - mrb_free(mrb, str->as.heap.ptr); -} - -#ifdef MRB_UTF8_STRING -static const char utf8len_codepage[256] = -{ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1, -}; - -static mrb_int -utf8len(const char* p, const char* e) -{ - mrb_int len; - mrb_int i; - - len = utf8len_codepage[(unsigned char)*p]; - if (p + len > e) return 1; - for (i = 1; i < len; ++i) - if ((p[i] & 0xc0) != 0x80) - return 1; - return len; -} - -static mrb_int -utf8_strlen(mrb_value str, mrb_int len) -{ - mrb_int total = 0; - char* p = RSTRING_PTR(str); - char* e = p; - if (RSTRING(str)->flags & MRB_STR_NO_UTF) { - return RSTRING_LEN(str); - } - e += len < 0 ? RSTRING_LEN(str) : len; - while (p<e) { - p += utf8len(p, e); - total++; - } - if (RSTRING_LEN(str) == total) { - RSTRING(str)->flags |= MRB_STR_NO_UTF; - } - return total; -} - -#define RSTRING_CHAR_LEN(s) utf8_strlen(s, -1) - -/* map character index to byte offset index */ -static mrb_int -chars2bytes(mrb_value s, mrb_int off, mrb_int idx) -{ - mrb_int i, b, n; - const char *p = RSTRING_PTR(s) + off; - const char *e = RSTRING_END(s); - - for (b=i=0; p<e && i<idx; i++) { - n = utf8len(p, e); - b += n; - p += n; - } - return b; -} - -/* map byte offset to character index */ -static mrb_int -bytes2chars(char *p, mrb_int bi) -{ - mrb_int i, b, n; - - for (b=i=0; b<bi; i++) { - n = utf8len_codepage[(unsigned char)*p]; - b += n; - p += n; - } - if (b != bi) return -1; - return i; -} - -#define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value(); -#else -#define RSTRING_CHAR_LEN(s) RSTRING_LEN(s) -#define chars2bytes(p, off, ci) (ci) -#define bytes2chars(p, bi) (bi) -#define BYTES_ALIGN_CHECK(pos) -#endif - -static inline mrb_int -mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) -{ - const unsigned char *x = xs, *xe = xs + m; - const unsigned char *y = ys; - int i; - ptrdiff_t qstable[256]; - - /* Preprocessing */ - for (i = 0; i < 256; ++i) - qstable[i] = m + 1; - for (; x < xe; ++x) - qstable[*x] = xe - x; - /* Searching */ - for (; y + m <= ys + n; y += *(qstable + y[m])) { - if (*xs == *y && memcmp(xs, y, m) == 0) - return (mrb_int)(y - ys); - } - return -1; -} - -static mrb_int -mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) -{ - const unsigned char *x = (const unsigned char *)x0, *y = (const unsigned char *)y0; - - if (m > n) return -1; - else if (m == n) { - return memcmp(x0, y0, m) == 0 ? 0 : -1; - } - else if (m < 1) { - return 0; - } - else if (m == 1) { - const unsigned char *ys = (const unsigned char *)memchr(y, *x, n); - - if (ys) - return (mrb_int)(ys - y); - else - return -1; - } - return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n); -} - -static void -str_make_shared(mrb_state *mrb, struct RString *s) -{ - if (!RSTR_SHARED_P(s)) { - mrb_shared_string *shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); - - shared->refcnt = 1; - if (RSTR_EMBED_P(s)) { - const mrb_int len = RSTR_EMBED_LEN(s); - char *const tmp = (char *)mrb_malloc(mrb, len+1); - memcpy(tmp, s->as.ary, len); - tmp[len] = '\0'; - RSTR_UNSET_EMBED_FLAG(s); - s->as.heap.ptr = tmp; - s->as.heap.len = len; - shared->nofree = FALSE; - shared->ptr = s->as.heap.ptr; - } - else if (RSTR_NOFREE_P(s)) { - shared->nofree = TRUE; - shared->ptr = s->as.heap.ptr; - RSTR_UNSET_NOFREE_FLAG(s); - } - else { - shared->nofree = FALSE; - if (s->as.heap.aux.capa > s->as.heap.len) { - s->as.heap.ptr = shared->ptr = (char *)mrb_realloc(mrb, s->as.heap.ptr, s->as.heap.len+1); - } - else { - shared->ptr = s->as.heap.ptr; - } - } - shared->len = s->as.heap.len; - s->as.heap.aux.shared = shared; - RSTR_SET_SHARED_FLAG(s); - } -} - -static mrb_value -byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) -{ - struct RString *orig, *s; - mrb_shared_string *shared; - - orig = mrb_str_ptr(str); - if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) { - s = str_new(mrb, orig->as.ary+beg, len); - } - else { - str_make_shared(mrb, orig); - shared = orig->as.heap.aux.shared; - s = mrb_obj_alloc_string(mrb); - s->as.heap.ptr = orig->as.heap.ptr + beg; - s->as.heap.len = len; - s->as.heap.aux.shared = shared; - RSTR_SET_SHARED_FLAG(s); - shared->refcnt++; - } - - return mrb_obj_value(s); -} -#ifdef MRB_UTF8_STRING -static inline mrb_value -str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) -{ - beg = chars2bytes(str, 0, beg); - len = chars2bytes(str, beg, len); - - return byte_subseq(mrb, str, beg, len); -} -#else -#define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len) -#endif - -static mrb_value -str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) -{ - mrb_int clen = RSTRING_CHAR_LEN(str); - - if (len < 0) return mrb_nil_value(); - if (clen == 0) { - len = 0; - } - else if (beg < 0) { - beg = clen + beg; - } - if (beg > clen) return mrb_nil_value(); - if (beg < 0) { - beg += clen; - if (beg < 0) return mrb_nil_value(); - } - if (len > clen - beg) - len = clen - beg; - if (len <= 0) { - len = 0; - } - return str_subseq(mrb, str, beg, len); -} - -MRB_API mrb_int -mrb_str_index(mrb_state *mrb, mrb_value str, const char *sptr, mrb_int slen, mrb_int offset) -{ - mrb_int pos; - char *s; - mrb_int len; - - len = RSTRING_LEN(str); - if (offset < 0) { - offset += len; - if (offset < 0) return -1; - } - if (len - offset < slen) return -1; - s = RSTRING_PTR(str); - if (offset) { - s += offset; - } - if (slen == 0) return offset; - /* need proceed one character at a time */ - len = RSTRING_LEN(str) - offset; - pos = mrb_memsearch(sptr, slen, s, len); - if (pos < 0) return pos; - return pos + offset; -} - -static mrb_int -str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset) -{ - const char *ptr; - mrb_int len; - - ptr = RSTRING_PTR(str2); - len = RSTRING_LEN(str2); - - return mrb_str_index(mrb, str, ptr, len, offset); -} - -static void -check_frozen(mrb_state *mrb, struct RString *s) -{ - if (MRB_FROZEN_P(s)) { - mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string"); - } -} - -static mrb_value -str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) -{ - long len; - - check_frozen(mrb, s1); - if (s1 == s2) return mrb_obj_value(s1); - s1->flags &= ~MRB_STR_NO_UTF; - s1->flags |= s2->flags&MRB_STR_NO_UTF; - len = RSTR_LEN(s2); - if (RSTR_SHARED_P(s1)) { - str_decref(mrb, s1->as.heap.aux.shared); - } - else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1)) { - mrb_free(mrb, s1->as.heap.ptr); - } - - RSTR_UNSET_NOFREE_FLAG(s1); - - if (RSTR_SHARED_P(s2)) { -L_SHARE: - RSTR_UNSET_EMBED_FLAG(s1); - s1->as.heap.ptr = s2->as.heap.ptr; - s1->as.heap.len = len; - s1->as.heap.aux.shared = s2->as.heap.aux.shared; - RSTR_SET_SHARED_FLAG(s1); - s1->as.heap.aux.shared->refcnt++; - } - else { - if (len <= RSTRING_EMBED_LEN_MAX) { - RSTR_UNSET_SHARED_FLAG(s1); - RSTR_SET_EMBED_FLAG(s1); - memcpy(s1->as.ary, RSTR_PTR(s2), len); - RSTR_SET_EMBED_LEN(s1, len); - } - else { - str_make_shared(mrb, s2); - goto L_SHARE; - } - } - - return mrb_obj_value(s1); -} - -static mrb_int -str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) -{ - char *s, *sbeg, *t; - struct RString *ps = mrb_str_ptr(str); - mrb_int len = RSTRING_LEN(sub); - - /* substring longer than string */ - if (RSTR_LEN(ps) < len) return -1; - if (RSTR_LEN(ps) - pos < len) { - pos = RSTR_LEN(ps) - len; - } - sbeg = RSTR_PTR(ps); - s = RSTR_PTR(ps) + pos; - t = RSTRING_PTR(sub); - if (len) { - while (sbeg <= s) { - if (memcmp(s, t, len) == 0) { - return (mrb_int)(s - RSTR_PTR(ps)); - } - s--; - } - return -1; - } - else { - return pos; - } -} - -MRB_API mrb_int -mrb_str_strlen(mrb_state *mrb, struct RString *s) -{ - mrb_int i, max = RSTR_LEN(s); - char *p = RSTR_PTR(s); - - if (!p) return 0; - for (i=0; i<max; i++) { - if (p[i] == '\0') { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); - } - } - return max; -} - -#ifdef _WIN32 -#include <windows.h> - -char* -mrb_utf8_from_locale(const char *str, int len) -{ - wchar_t* wcsp; - char* mbsp; - int mbssize, wcssize; - - if (len == 0) - return strdup(""); - if (len == -1) - len = (int)strlen(str); - wcssize = MultiByteToWideChar(GetACP(), 0, str, len, NULL, 0); - wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); - if (!wcsp) - return NULL; - wcssize = MultiByteToWideChar(GetACP(), 0, str, len, wcsp, wcssize + 1); - wcsp[wcssize] = 0; - - mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL); - mbsp = (char*) malloc((mbssize + 1)); - if (!mbsp) { - free(wcsp); - return NULL; - } - mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL); - mbsp[mbssize] = 0; - free(wcsp); - return mbsp; -} - -char* -mrb_locale_from_utf8(const char *utf8, int len) -{ - wchar_t* wcsp; - char* mbsp; - int mbssize, wcssize; - - if (len == 0) - return strdup(""); - if (len == -1) - len = (int)strlen(utf8); - wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); - wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); - if (!wcsp) - return NULL; - wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, wcsp, wcssize + 1); - wcsp[wcssize] = 0; - mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL); - mbsp = (char*) malloc((mbssize + 1)); - if (!mbsp) { - free(wcsp); - return NULL; - } - mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL); - mbsp[mbssize] = 0; - free(wcsp); - return mbsp; -} -#endif - -MRB_API void -mrb_str_modify(mrb_state *mrb, struct RString *s) -{ - check_frozen(mrb, s); - s->flags &= ~MRB_STR_NO_UTF; - if (RSTR_SHARED_P(s)) { - mrb_shared_string *shared = s->as.heap.aux.shared; - - if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { - s->as.heap.ptr = shared->ptr; - s->as.heap.aux.capa = shared->len; - RSTR_PTR(s)[s->as.heap.len] = '\0'; - mrb_free(mrb, shared); - } - else { - char *ptr, *p; - mrb_int len; - - p = RSTR_PTR(s); - len = s->as.heap.len; - if (len < RSTRING_EMBED_LEN_MAX) { - RSTR_SET_EMBED_FLAG(s); - RSTR_SET_EMBED_LEN(s, len); - ptr = RSTR_PTR(s); - } - else { - ptr = (char *)mrb_malloc(mrb, (size_t)len + 1); - s->as.heap.ptr = ptr; - s->as.heap.aux.capa = len; - } - if (p) { - memcpy(ptr, p, len); - } - ptr[len] = '\0'; - str_decref(mrb, shared); - } - RSTR_UNSET_SHARED_FLAG(s); - return; - } - if (RSTR_NOFREE_P(s)) { - char *p = s->as.heap.ptr; - mrb_int len = s->as.heap.len; - - RSTR_UNSET_NOFREE_FLAG(s); - if (len < RSTRING_EMBED_LEN_MAX) { - RSTR_SET_EMBED_FLAG(s); - RSTR_SET_EMBED_LEN(s, len); - } - else { - s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); - s->as.heap.aux.capa = len; - } - if (p) { - memcpy(RSTR_PTR(s), p, len); - } - RSTR_PTR(s)[len] = '\0'; - return; - } -} - -MRB_API mrb_value -mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len) -{ - mrb_int slen; - struct RString *s = mrb_str_ptr(str); - - mrb_str_modify(mrb, s); - slen = RSTR_LEN(s); - if (len != slen) { - if (slen < len || slen - len > 256) { - resize_capa(mrb, s, len); - } - RSTR_SET_LEN(s, len); - RSTR_PTR(s)[len] = '\0'; /* sentinel */ - } - return str; -} - -MRB_API char* -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"); - } - - s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0)); - if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); - } - return RSTR_PTR(s); -} - -/* - * call-seq: (Caution! String("abcd") change) - * String("abcdefg") = String("abcd") + String("efg") - * - * Returns a new string object containing a copy of <i>str</i>. - */ -MRB_API void -mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other) -{ - if (!mrb_string_p(other)) { - other = mrb_str_to_str(mrb, other); - } - mrb_str_cat_str(mrb, self, other); -} - -/* - * call-seq: (Caution! String("abcd") remain) - * String("abcdefg") = String("abcd") + String("efg") - * - * Returns a new string object containing a copy of <i>str</i>. - */ -MRB_API mrb_value -mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b) -{ - struct RString *s = mrb_str_ptr(a); - struct RString *s2 = mrb_str_ptr(b); - struct RString *t; - - t = str_new(mrb, 0, RSTR_LEN(s) + RSTR_LEN(s2)); - memcpy(RSTR_PTR(t), RSTR_PTR(s), RSTR_LEN(s)); - memcpy(RSTR_PTR(t) + RSTR_LEN(s), RSTR_PTR(s2), RSTR_LEN(s2)); - - return mrb_obj_value(t); -} - -/* 15.2.10.5.2 */ - -/* - * call-seq: (Caution! String("abcd") remain) for stack_argument - * String("abcdefg") = String("abcd") + String("efg") - * - * Returns a new string object containing a copy of <i>str</i>. - */ -static mrb_value -mrb_str_plus_m(mrb_state *mrb, mrb_value self) -{ - mrb_value str; - - mrb_get_args(mrb, "S", &str); - return mrb_str_plus(mrb, self, str); -} - -/* 15.2.10.5.26 */ -/* 15.2.10.5.33 */ -/* - * call-seq: - * "abcd".size => int - * - * Returns the length of string. - */ -static mrb_value -mrb_str_size(mrb_state *mrb, mrb_value self) -{ - mrb_int len = RSTRING_CHAR_LEN(self); - return mrb_fixnum_value(len); -} - -static mrb_value -mrb_str_bytesize(mrb_state *mrb, mrb_value self) -{ - mrb_int len = RSTRING_LEN(self); - return mrb_fixnum_value(len); -} - -/* 15.2.10.5.1 */ -/* - * call-seq: - * str * integer => new_str - * - * Copy---Returns a new <code>String</code> containing <i>integer</i> copies of - * the receiver. - * - * "Ho! " * 3 #=> "Ho! Ho! Ho! " - */ -static mrb_value -mrb_str_times(mrb_state *mrb, mrb_value self) -{ - mrb_int n,len,times; - struct RString *str2; - char *p; - - mrb_get_args(mrb, "i", ×); - if (times < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); - } - if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big"); - } - - len = RSTRING_LEN(self)*times; - str2 = str_new(mrb, 0, len); - str_with_class(mrb, str2, self); - p = RSTR_PTR(str2); - if (len > 0) { - n = RSTRING_LEN(self); - memcpy(p, RSTRING_PTR(self), n); - while (n <= len/2) { - memcpy(p + n, p, n); - n *= 2; - } - memcpy(p + n, p, len-n); - } - p[RSTR_LEN(str2)] = '\0'; - - return mrb_obj_value(str2); -} -/* -------------------------------------------------------------- */ - -#define lesser(a,b) (((a)>(b))?(b):(a)) - -/* ---------------------------*/ -/* - * call-seq: - * mrb_value str1 <=> mrb_value str2 => int - * > 1 - * = 0 - * < -1 - */ -MRB_API int -mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2) -{ - mrb_int len; - mrb_int retval; - struct RString *s1 = mrb_str_ptr(str1); - struct RString *s2 = mrb_str_ptr(str2); - - len = lesser(RSTR_LEN(s1), RSTR_LEN(s2)); - retval = memcmp(RSTR_PTR(s1), RSTR_PTR(s2), len); - if (retval == 0) { - if (RSTR_LEN(s1) == RSTR_LEN(s2)) return 0; - if (RSTR_LEN(s1) > RSTR_LEN(s2)) return 1; - return -1; - } - if (retval > 0) return 1; - return -1; -} - -/* 15.2.10.5.3 */ - -/* - * call-seq: - * str <=> other_str => -1, 0, +1 - * - * Comparison---Returns -1 if <i>other_str</i> is less than, 0 if - * <i>other_str</i> is equal to, and +1 if <i>other_str</i> is greater than - * <i>str</i>. If the strings are of different lengths, and the strings are - * equal when compared up to the shortest length, then the longer string is - * considered greater than the shorter one. If the variable <code>$=</code> is - * <code>false</code>, the comparison is based on comparing the binary values - * of each character in the string. In older versions of Ruby, setting - * <code>$=</code> allowed case-insensitive comparisons; this is now deprecated - * in favor of using <code>String#casecmp</code>. - * - * <code><=></code> is the basis for the methods <code><</code>, - * <code><=</code>, <code>></code>, <code>>=</code>, and <code>between?</code>, - * included from module <code>Comparable</code>. The method - * <code>String#==</code> does not use <code>Comparable#==</code>. - * - * "abcdef" <=> "abcde" #=> 1 - * "abcdef" <=> "abcdef" #=> 0 - * "abcdef" <=> "abcdefg" #=> -1 - * "abcdef" <=> "ABCDEF" #=> 1 - */ -static mrb_value -mrb_str_cmp_m(mrb_state *mrb, mrb_value str1) -{ - mrb_value str2; - mrb_int result; - - mrb_get_args(mrb, "o", &str2); - if (!mrb_string_p(str2)) { - if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) { - return mrb_nil_value(); - } - else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) { - return mrb_nil_value(); - } - else { - mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1); - - if (!mrb_nil_p(tmp)) return mrb_nil_value(); - if (!mrb_fixnum_p(tmp)) { - return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp); - } - result = -mrb_fixnum(tmp); - } - } - else { - result = mrb_str_cmp(mrb, str1, str2); - } - return mrb_fixnum_value(result); -} - -static mrb_bool -str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2) -{ - const mrb_int len = RSTRING_LEN(str1); - - if (len != RSTRING_LEN(str2)) return FALSE; - if (memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), (size_t)len) == 0) - return TRUE; - return FALSE; -} - -MRB_API mrb_bool -mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2) -{ - if (mrb_immediate_p(str2)) return FALSE; - if (!mrb_string_p(str2)) { - if (mrb_nil_p(str2)) return FALSE; - if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_str"))) { - return FALSE; - } - str2 = mrb_funcall(mrb, str2, "to_str", 0); - return mrb_equal(mrb, str2, str1); - } - return str_eql(mrb, str1, str2); -} - -/* 15.2.10.5.4 */ -/* - * call-seq: - * str == obj => true or false - * - * Equality--- - * If <i>obj</i> is not a <code>String</code>, returns <code>false</code>. - * Otherwise, returns <code>false</code> or <code>true</code> - * - * caution:if <i>str</i> <code><=></code> <i>obj</i> returns zero. - */ -static mrb_value -mrb_str_equal_m(mrb_state *mrb, mrb_value str1) -{ - mrb_value str2; - - mrb_get_args(mrb, "o", &str2); - - return mrb_bool_value(mrb_str_equal(mrb, str1, str2)); -} -/* ---------------------------------- */ -MRB_API mrb_value -mrb_str_to_str(mrb_state *mrb, mrb_value str) -{ - mrb_value s; - - if (!mrb_string_p(str)) { - s = mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str"); - if (mrb_nil_p(s)) { - s = mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s"); - } - return s; - } - return str; -} - -MRB_API const 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_API mrb_int -mrb_string_value_len(mrb_state *mrb, mrb_value ptr) -{ - mrb_value str = mrb_str_to_str(mrb, ptr); - return RSTRING_LEN(str); -} - -void -mrb_noregexp(mrb_state *mrb, mrb_value self) -{ - mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented"); -} - -void -mrb_regexp_check(mrb_state *mrb, mrb_value obj) -{ - if (mrb_regexp_p(mrb, obj)) { - mrb_noregexp(mrb, obj); - } -} - -MRB_API mrb_value -mrb_str_dup(mrb_state *mrb, mrb_value str) -{ - struct RString *s = mrb_str_ptr(str); - struct RString *dup = str_new(mrb, 0, 0); - - str_with_class(mrb, dup, str); - return str_replace(mrb, dup, s); -} - -static mrb_value -mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) -{ - mrb_int idx; - - mrb_regexp_check(mrb, indx); - switch (mrb_type(indx)) { - case MRB_TT_FIXNUM: - idx = mrb_fixnum(indx); - -num_index: - str = str_substr(mrb, str, idx, 1); - if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value(); - return str; - - case MRB_TT_STRING: - if (str_index_str(mrb, str, indx, 0) != -1) - return mrb_str_dup(mrb, indx); - return mrb_nil_value(); - - case MRB_TT_RANGE: - goto range_arg; - - default: - indx = mrb_Integer(mrb, indx); - if (mrb_nil_p(indx)) { - range_arg: - { - mrb_int beg, len; - - len = RSTRING_CHAR_LEN(str); - switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) { - case 1: - return str_subseq(mrb, str, beg, len); - case 2: - return mrb_nil_value(); - default: - break; - } - } - mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum"); - } - idx = mrb_fixnum(indx); - goto num_index; - } - return mrb_nil_value(); /* not reached */ -} - -/* 15.2.10.5.6 */ -/* 15.2.10.5.34 */ -/* - * call-seq: - * str[fixnum] => fixnum or nil - * str[fixnum, fixnum] => new_str or nil - * str[range] => new_str or nil - * str[regexp] => new_str or nil - * str[regexp, fixnum] => new_str or nil - * str[other_str] => new_str or nil - * str.slice(fixnum) => fixnum or nil - * str.slice(fixnum, fixnum) => new_str or nil - * str.slice(range) => new_str or nil - * str.slice(other_str) => new_str or nil - * - * Element Reference---If passed a single <code>Fixnum</code>, returns the code - * of the character at that position. If passed two <code>Fixnum</code> - * objects, returns a substring starting at the offset given by the first, and - * a length given by the second. If given a range, a substring containing - * characters at offsets given by the range is returned. In all three cases, if - * an offset is negative, it is counted from the end of <i>str</i>. Returns - * <code>nil</code> if the initial offset falls outside the string, the length - * is negative, or the beginning of the range is greater than the end. - * - * If a <code>String</code> is given, that string is returned if it occurs in - * <i>str</i>. In both cases, <code>nil</code> is returned if there is no - * match. - * - * a = "hello there" - * a[1] #=> 101(1.8.7) "e"(1.9.2) - * a[1.1] #=> "e"(1.9.2) - * a[1,3] #=> "ell" - * a[1..3] #=> "ell" - * a[-3,2] #=> "er" - * a[-4..-2] #=> "her" - * a[12..-1] #=> nil - * a[-2..-4] #=> "" - * a["lo"] #=> "lo" - * a["bye"] #=> nil - */ -static mrb_value -mrb_str_aref_m(mrb_state *mrb, mrb_value str) -{ - mrb_value a1, a2; - int argc; - - argc = mrb_get_args(mrb, "o|o", &a1, &a2); - if (argc == 2) { - mrb_int n1, n2; - - mrb_regexp_check(mrb, a1); - mrb_get_args(mrb, "ii", &n1, &n2); - return str_substr(mrb, str, n1, n2); - } - if (argc != 1) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc)); - } - return mrb_str_aref(mrb, str, a1); -} - -/* 15.2.10.5.8 */ -/* - * call-seq: - * str.capitalize! => str or nil - * - * Modifies <i>str</i> by converting the first character to uppercase and the - * remainder to lowercase. Returns <code>nil</code> if no changes are made. - * - * a = "hello" - * a.capitalize! #=> "Hello" - * a #=> "Hello" - * a.capitalize! #=> nil - */ -static mrb_value -mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str) -{ - char *p, *pend; - mrb_bool modify = FALSE; - struct RString *s = mrb_str_ptr(str); - - mrb_str_modify(mrb, s); - if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value(); - p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s); - if (ISLOWER(*p)) { - *p = TOUPPER(*p); - modify = TRUE; - } - while (++p < pend) { - if (ISUPPER(*p)) { - *p = TOLOWER(*p); - modify = TRUE; - } - } - if (modify) return str; - return mrb_nil_value(); -} - -/* 15.2.10.5.7 */ -/* - * call-seq: - * str.capitalize => new_str - * - * Returns a copy of <i>str</i> with the first character converted to uppercase - * and the remainder to lowercase. - * - * "hello".capitalize #=> "Hello" - * "HELLO".capitalize #=> "Hello" - * "123ABC".capitalize #=> "123abc" - */ -static mrb_value -mrb_str_capitalize(mrb_state *mrb, mrb_value self) -{ - mrb_value str; - - str = mrb_str_dup(mrb, self); - mrb_str_capitalize_bang(mrb, str); - return str; -} - -/* 15.2.10.5.10 */ -/* - * call-seq: - * str.chomp!(separator="\n") => str or nil - * - * Modifies <i>str</i> in place as described for <code>String#chomp</code>, - * returning <i>str</i>, or <code>nil</code> if no modifications were made. - */ -static mrb_value -mrb_str_chomp_bang(mrb_state *mrb, mrb_value str) -{ - mrb_value rs; - mrb_int newline; - char *p, *pp; - mrb_int rslen; - mrb_int len; - mrb_int argc; - struct RString *s = mrb_str_ptr(str); - - mrb_str_modify(mrb, s); - argc = mrb_get_args(mrb, "|S", &rs); - len = RSTR_LEN(s); - if (argc == 0) { - if (len == 0) return mrb_nil_value(); - smart_chomp: - if (RSTR_PTR(s)[len-1] == '\n') { - RSTR_SET_LEN(s, RSTR_LEN(s) - 1); - if (RSTR_LEN(s) > 0 && - RSTR_PTR(s)[RSTR_LEN(s)-1] == '\r') { - RSTR_SET_LEN(s, RSTR_LEN(s) - 1); - } - } - else if (RSTR_PTR(s)[len-1] == '\r') { - RSTR_SET_LEN(s, RSTR_LEN(s) - 1); - } - else { - return mrb_nil_value(); - } - RSTR_PTR(s)[RSTR_LEN(s)] = '\0'; - return str; - } - - if (len == 0 || mrb_nil_p(rs)) return mrb_nil_value(); - p = RSTR_PTR(s); - rslen = RSTRING_LEN(rs); - if (rslen == 0) { - while (len>0 && p[len-1] == '\n') { - len--; - if (len>0 && p[len-1] == '\r') - len--; - } - if (len < RSTR_LEN(s)) { - RSTR_SET_LEN(s, len); - p[len] = '\0'; - return str; - } - return mrb_nil_value(); - } - if (rslen > len) return mrb_nil_value(); - newline = RSTRING_PTR(rs)[rslen-1]; - if (rslen == 1 && newline == '\n') - newline = RSTRING_PTR(rs)[rslen-1]; - if (rslen == 1 && newline == '\n') - goto smart_chomp; - - pp = p + len - rslen; - if (p[len-1] == newline && - (rslen <= 1 || - memcmp(RSTRING_PTR(rs), pp, rslen) == 0)) { - RSTR_SET_LEN(s, len - rslen); - p[RSTR_LEN(s)] = '\0'; - return str; - } - return mrb_nil_value(); -} - -/* 15.2.10.5.9 */ -/* - * call-seq: - * str.chomp(separator="\n") => new_str - * - * Returns a new <code>String</code> with the given record separator removed - * from the end of <i>str</i> (if present). If <code>$/</code> has not been - * changed from the default Ruby record separator, then <code>chomp</code> also - * removes carriage return characters (that is it will remove <code>\n</code>, - * <code>\r</code>, and <code>\r\n</code>). - * - * "hello".chomp #=> "hello" - * "hello\n".chomp #=> "hello" - * "hello\r\n".chomp #=> "hello" - * "hello\n\r".chomp #=> "hello\n" - * "hello\r".chomp #=> "hello" - * "hello \n there".chomp #=> "hello \n there" - * "hello".chomp("llo") #=> "he" - */ -static mrb_value -mrb_str_chomp(mrb_state *mrb, mrb_value self) -{ - mrb_value str; - - str = mrb_str_dup(mrb, self); - mrb_str_chomp_bang(mrb, str); - return str; -} - -/* 15.2.10.5.12 */ -/* - * call-seq: - * str.chop! => str or nil - * - * Processes <i>str</i> as for <code>String#chop</code>, returning <i>str</i>, - * or <code>nil</code> if <i>str</i> is the empty string. See also - * <code>String#chomp!</code>. - */ -static mrb_value -mrb_str_chop_bang(mrb_state *mrb, mrb_value str) -{ - struct RString *s = mrb_str_ptr(str); - - mrb_str_modify(mrb, s); - if (RSTR_LEN(s) > 0) { - mrb_int len; -#ifdef MRB_UTF8_STRING - const char* t = RSTR_PTR(s), *p = t; - const char* e = p + RSTR_LEN(s); - while (p<e) { - mrb_int clen = utf8len(p, e); - if (p + clen>=e) break; - p += clen; - } - len = p - t; -#else - len = RSTR_LEN(s) - 1; -#endif - if (RSTR_PTR(s)[len] == '\n') { - if (len > 0 && - RSTR_PTR(s)[len-1] == '\r') { - len--; - } - } - RSTR_SET_LEN(s, len); - RSTR_PTR(s)[len] = '\0'; - return str; - } - return mrb_nil_value(); -} - -/* 15.2.10.5.11 */ -/* - * call-seq: - * str.chop => new_str - * - * Returns a new <code>String</code> with the last character removed. If the - * string ends with <code>\r\n</code>, both characters are removed. Applying - * <code>chop</code> to an empty string returns an empty - * string. <code>String#chomp</code> is often a safer alternative, as it leaves - * the string unchanged if it doesn't end in a record separator. - * - * "string\r\n".chop #=> "string" - * "string\n\r".chop #=> "string\n" - * "string\n".chop #=> "string" - * "string".chop #=> "strin" - * "x".chop #=> "" - */ -static mrb_value -mrb_str_chop(mrb_state *mrb, mrb_value self) -{ - mrb_value str; - str = mrb_str_dup(mrb, self); - mrb_str_chop_bang(mrb, str); - return str; -} - -/* 15.2.10.5.14 */ -/* - * call-seq: - * str.downcase! => str or nil - * - * Downcases the contents of <i>str</i>, returning <code>nil</code> if no - * changes were made. - */ -static mrb_value -mrb_str_downcase_bang(mrb_state *mrb, mrb_value str) -{ - char *p, *pend; - mrb_bool modify = FALSE; - struct RString *s = mrb_str_ptr(str); - - mrb_str_modify(mrb, s); - p = RSTR_PTR(s); - pend = RSTR_PTR(s) + RSTR_LEN(s); - while (p < pend) { - if (ISUPPER(*p)) { - *p = TOLOWER(*p); - modify = TRUE; - } - p++; - } - - if (modify) return str; - return mrb_nil_value(); -} - -/* 15.2.10.5.13 */ -/* - * call-seq: - * str.downcase => new_str - * - * Returns a copy of <i>str</i> with all uppercase letters replaced with their - * lowercase counterparts. The operation is locale insensitive---only - * characters 'A' to 'Z' are affected. - * - * "hEllO".downcase #=> "hello" - */ -static mrb_value -mrb_str_downcase(mrb_state *mrb, mrb_value self) -{ - mrb_value str; - - str = mrb_str_dup(mrb, self); - mrb_str_downcase_bang(mrb, str); - return str; -} - -/* 15.2.10.5.16 */ -/* - * call-seq: - * str.empty? => true or false - * - * Returns <code>true</code> if <i>str</i> has a length of zero. - * - * "hello".empty? #=> false - * "".empty? #=> true - */ -static mrb_value -mrb_str_empty_p(mrb_state *mrb, mrb_value self) -{ - struct RString *s = mrb_str_ptr(self); - - return mrb_bool_value(RSTR_LEN(s) == 0); -} - -/* 15.2.10.5.17 */ -/* - * call-seq: - * str.eql?(other) => true or false - * - * Two strings are equal if the have the same length and content. - */ -static mrb_value -mrb_str_eql(mrb_state *mrb, mrb_value self) -{ - mrb_value str2; - mrb_bool eql_p; - - mrb_get_args(mrb, "o", &str2); - eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2); - - return mrb_bool_value(eql_p); -} - -MRB_API mrb_value -mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) -{ - return str_substr(mrb, str, beg, len); -} - -mrb_int -mrb_str_hash(mrb_state *mrb, mrb_value str) -{ - /* 1-8-7 */ - struct RString *s = mrb_str_ptr(str); - mrb_int len = RSTR_LEN(s); - char *p = RSTR_PTR(s); - uint64_t key = 0; - - while (len--) { - key = key*65599 + *p; - p++; - } - return (mrb_int)(key + (key>>5)); -} - -/* 15.2.10.5.20 */ -/* - * call-seq: - * str.hash => fixnum - * - * Return a hash based on the string's length and content. - */ -static mrb_value -mrb_str_hash_m(mrb_state *mrb, mrb_value self) -{ - mrb_int key = mrb_str_hash(mrb, self); - return mrb_fixnum_value(key); -} - -/* 15.2.10.5.21 */ -/* - * call-seq: - * str.include? other_str => true or false - * str.include? fixnum => true or false - * - * Returns <code>true</code> if <i>str</i> contains the given string or - * character. - * - * "hello".include? "lo" #=> true - * "hello".include? "ol" #=> false - * "hello".include? ?h #=> true - */ -static mrb_value -mrb_str_include(mrb_state *mrb, mrb_value self) -{ - mrb_value str2; - - mrb_get_args(mrb, "S", &str2); - if (str_index_str(mrb, self, str2, 0) < 0) - return mrb_bool_value(FALSE); - return mrb_bool_value(TRUE); -} - -/* 15.2.10.5.22 */ -/* - * call-seq: - * str.index(substring [, offset]) => fixnum or nil - * str.index(fixnum [, offset]) => fixnum or nil - * str.index(regexp [, offset]) => fixnum or nil - * - * Returns the index of the first occurrence of the given - * <i>substring</i>, - * character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. - * Returns - * <code>nil</code> if not found. - * If the second parameter is present, it - * specifies the position in the string to begin the search. - * - * "hello".index('e') #=> 1 - * "hello".index('lo') #=> 3 - * "hello".index('a') #=> nil - * "hello".index(101) #=> 1(101=0x65='e') - * "hello".index(/[aeiou]/, -3) #=> 4 - */ -static mrb_value -mrb_str_index_m(mrb_state *mrb, mrb_value str) -{ - mrb_value *argv; - mrb_int argc; - mrb_value sub; - mrb_int pos, clen; - - mrb_get_args(mrb, "*!", &argv, &argc); - if (argc == 2) { - mrb_get_args(mrb, "oi", &sub, &pos); - } - else { - pos = 0; - if (argc > 0) - sub = argv[0]; - else - sub = mrb_nil_value(); - } - mrb_regexp_check(mrb, sub); - clen = RSTRING_CHAR_LEN(str); - if (pos < 0) { - pos += clen; - if (pos < 0) { - return mrb_nil_value(); - } - } - if (pos > clen) return mrb_nil_value(); - pos = chars2bytes(str, 0, pos); - - switch (mrb_type(sub)) { - default: { - mrb_value tmp; - - tmp = mrb_check_string_type(mrb, sub); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); - } - sub = tmp; - } - /* fall through */ - case MRB_TT_STRING: - pos = str_index_str(mrb, str, sub, pos); - break; - } - - if (pos == -1) return mrb_nil_value(); - pos = bytes2chars(RSTRING_PTR(str), pos); - BYTES_ALIGN_CHECK(pos); - return mrb_fixnum_value(pos); -} - -#define STR_REPLACE_SHARED_MIN 10 - -/* 15.2.10.5.24 */ -/* 15.2.10.5.28 */ -/* - * call-seq: - * str.replace(other_str) => str - * - * s = "hello" #=> "hello" - * s.replace "world" #=> "world" - */ -static mrb_value -mrb_str_replace(mrb_state *mrb, mrb_value str) -{ - mrb_value str2; - - mrb_get_args(mrb, "S", &str2); - return str_replace(mrb, mrb_str_ptr(str), mrb_str_ptr(str2)); -} - -/* 15.2.10.5.23 */ -/* - * call-seq: - * String.new(str="") => new_str - * - * Returns a new string object containing a copy of <i>str</i>. - */ -static mrb_value -mrb_str_init(mrb_state *mrb, mrb_value self) -{ - mrb_value str2; - - if (mrb_get_args(mrb, "|S", &str2) == 0) { - struct RString *s = str_new(mrb, 0, 0); - str2 = mrb_obj_value(s); - } - str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2)); - return self; -} - -/* 15.2.10.5.25 */ -/* 15.2.10.5.41 */ -/* - * call-seq: - * str.intern => symbol - * str.to_sym => symbol - * - * Returns the <code>Symbol</code> corresponding to <i>str</i>, creating the - * symbol if it did not previously exist. See <code>Symbol#id2name</code>. - * - * "Koala".intern #=> :Koala - * s = 'cat'.to_sym #=> :cat - * s == :cat #=> true - * s = '@cat'.to_sym #=> :@cat - * s == :@cat #=> true - * - * This can also be used to create symbols that cannot be represented using the - * <code>:xxx</code> notation. - * - * 'cat and dog'.to_sym #=> :"cat and dog" - */ -MRB_API mrb_value -mrb_str_intern(mrb_state *mrb, mrb_value self) -{ - return mrb_symbol_value(mrb_intern_str(mrb, self)); -} -/* ---------------------------------- */ -MRB_API mrb_value -mrb_obj_as_string(mrb_state *mrb, mrb_value obj) -{ - mrb_value str; - - if (mrb_string_p(obj)) { - return obj; - } - str = mrb_funcall(mrb, obj, "to_s", 0); - if (!mrb_string_p(str)) - return mrb_any_to_s(mrb, obj); - return str; -} - -MRB_API mrb_value -mrb_ptr_to_str(mrb_state *mrb, void *p) -{ - struct RString *p_str; - char *p1; - char *p2; - uintptr_t n = (uintptr_t)p; - - p_str = str_new(mrb, NULL, 2 + sizeof(uintptr_t) * CHAR_BIT / 4); - p1 = RSTR_PTR(p_str); - *p1++ = '0'; - *p1++ = 'x'; - p2 = p1; - - do { - *p2++ = mrb_digitmap[n % 16]; - n /= 16; - } while (n > 0); - *p2 = '\0'; - RSTR_SET_LEN(p_str, (mrb_int)(p2 - RSTR_PTR(p_str))); - - while (p1 < p2) { - const char c = *p1; - *p1++ = *--p2; - *p2 = c; - } - - return mrb_obj_value(p_str); -} - -MRB_API mrb_value -mrb_string_type(mrb_state *mrb, mrb_value str) -{ - return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str"); -} - -MRB_API mrb_value -mrb_check_string_type(mrb_state *mrb, mrb_value str) -{ - return mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str"); -} - -/* 15.2.10.5.30 */ -/* - * call-seq: - * str.reverse! => str - * - * Reverses <i>str</i> in place. - */ -static mrb_value -mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) -{ -#ifdef MRB_UTF8_STRING - mrb_int utf8_len = RSTRING_CHAR_LEN(str); - mrb_int len = RSTRING_LEN(str); - - if (utf8_len == len) goto bytes; - if (utf8_len > 1) { - char *buf; - char *p, *e, *r; - - mrb_str_modify(mrb, mrb_str_ptr(str)); - len = RSTRING_LEN(str); - buf = (char*)mrb_malloc(mrb, (size_t)len); - p = buf; - e = buf + len; - - memcpy(buf, RSTRING_PTR(str), len); - r = RSTRING_PTR(str) + len; - - while (p<e) { - mrb_int clen = utf8len(p, e); - r -= clen; - memcpy(r, p, clen); - p += clen; - } - mrb_free(mrb, buf); - } - return str; - - bytes: -#endif - { - struct RString *s = mrb_str_ptr(str); - char *p, *e; - char c; - - mrb_str_modify(mrb, s); - if (RSTR_LEN(s) > 1) { - p = RSTR_PTR(s); - e = p + RSTR_LEN(s) - 1; - while (p < e) { - c = *p; - *p++ = *e; - *e-- = c; - } - } - return str; - } -} - -/* ---------------------------------- */ -/* 15.2.10.5.29 */ -/* - * call-seq: - * str.reverse => new_str - * - * Returns a new string with the characters from <i>str</i> in reverse order. - * - * "stressed".reverse #=> "desserts" - */ -static mrb_value -mrb_str_reverse(mrb_state *mrb, mrb_value str) -{ - mrb_value str2 = mrb_str_dup(mrb, str); - mrb_str_reverse_bang(mrb, str2); - return str2; -} - -/* 15.2.10.5.31 */ -/* - * call-seq: - * str.rindex(substring [, fixnum]) => fixnum or nil - * str.rindex(fixnum [, fixnum]) => fixnum or nil - * str.rindex(regexp [, fixnum]) => fixnum or nil - * - * Returns the index of the last occurrence of the given <i>substring</i>, - * character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns - * <code>nil</code> if not found. If the second parameter is present, it - * specifies the position in the string to end the search---characters beyond - * this point will not be considered. - * - * "hello".rindex('e') #=> 1 - * "hello".rindex('l') #=> 3 - * "hello".rindex('a') #=> nil - * "hello".rindex(101) #=> 1 - * "hello".rindex(/[aeiou]/, -2) #=> 1 - */ -static mrb_value -mrb_str_rindex(mrb_state *mrb, mrb_value str) -{ - mrb_value *argv; - mrb_int argc; - mrb_value sub; - mrb_int pos, len = RSTRING_CHAR_LEN(str); - - mrb_get_args(mrb, "*!", &argv, &argc); - if (argc == 2) { - mrb_get_args(mrb, "oi", &sub, &pos); - if (pos < 0) { - pos += len; - if (pos < 0) { - mrb_regexp_check(mrb, sub); - return mrb_nil_value(); - } - } - if (pos > len) pos = len; - } - else { - pos = len; - if (argc > 0) - sub = argv[0]; - else - sub = mrb_nil_value(); - } - pos = chars2bytes(str, 0, pos); - mrb_regexp_check(mrb, sub); - - switch (mrb_type(sub)) { - default: { - mrb_value tmp; - - tmp = mrb_check_string_type(mrb, sub); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); - } - sub = tmp; - } - /* fall through */ - case MRB_TT_STRING: - pos = str_rindex(mrb, str, sub, pos); - if (pos >= 0) { - pos = bytes2chars(RSTRING_PTR(str), pos); - BYTES_ALIGN_CHECK(pos); - return mrb_fixnum_value(pos); - } - break; - - } /* end of switch (TYPE(sub)) */ - return mrb_nil_value(); -} - -/* 15.2.10.5.35 */ - -/* - * call-seq: - * str.split(pattern="\n", [limit]) => anArray - * - * Divides <i>str</i> into substrings based on a delimiter, returning an array - * of these substrings. - * - * If <i>pattern</i> is a <code>String</code>, then its contents are used as - * the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single - * space, <i>str</i> is split on whitespace, with leading whitespace and runs - * of contiguous whitespace characters ignored. - * - * If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the - * pattern matches. Whenever the pattern matches a zero-length string, - * <i>str</i> is split into individual characters. - * - * If <i>pattern</i> is omitted, the value of <code>$;</code> is used. If - * <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is - * split on whitespace as if ' ' were specified. - * - * If the <i>limit</i> parameter is omitted, trailing null fields are - * suppressed. If <i>limit</i> is a positive number, at most that number of - * fields will be returned (if <i>limit</i> is <code>1</code>, the entire - * string is returned as the only entry in an array). If negative, there is no - * limit to the number of fields returned, and trailing null fields are not - * suppressed. - * - * " now's the time".split #=> ["now's", "the", "time"] - * " now's the time".split(' ') #=> ["now's", "the", "time"] - * " now's the time".split(/ /) #=> ["", "now's", "", "the", "time"] - * "hello".split(//) #=> ["h", "e", "l", "l", "o"] - * "hello".split(//, 3) #=> ["h", "e", "llo"] - * - * "mellow yellow".split("ello") #=> ["m", "w y", "w"] - * "1,2,,3,4,,".split(',') #=> ["1", "2", "", "3", "4"] - * "1,2,,3,4,,".split(',', 4) #=> ["1", "2", "", "3,4,,"] - * "1,2,,3,4,,".split(',', -4) #=> ["1", "2", "", "3", "4", "", ""] - */ - -static mrb_value -mrb_str_split_m(mrb_state *mrb, mrb_value str) -{ - int argc; - mrb_value spat = mrb_nil_value(); - enum {awk, string, regexp} split_type = string; - mrb_int i = 0; - mrb_int beg; - mrb_int end; - mrb_int lim = 0; - mrb_bool lim_p; - mrb_value result, tmp; - - argc = mrb_get_args(mrb, "|oi", &spat, &lim); - lim_p = (lim > 0 && argc == 2); - if (argc == 2) { - if (lim == 1) { - if (RSTRING_LEN(str) == 0) - return mrb_ary_new_capa(mrb, 0); - return mrb_ary_new_from_values(mrb, 1, &str); - } - i = 1; - } - - if (argc == 0 || mrb_nil_p(spat)) { - split_type = awk; - } - else { - if (mrb_string_p(spat)) { - split_type = string; - if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') { - split_type = awk; - } - } - else { - mrb_noregexp(mrb, str); - } - } - - result = mrb_ary_new(mrb); - beg = 0; - if (split_type == awk) { - mrb_bool skip = TRUE; - mrb_int idx = 0; - mrb_int str_len = RSTRING_LEN(str); - unsigned int c; - int ai = mrb_gc_arena_save(mrb); - - idx = end = beg; - while (idx < str_len) { - c = (unsigned char)RSTRING_PTR(str)[idx++]; - if (skip) { - if (ISSPACE(c)) { - beg = idx; - } - else { - end = idx; - skip = FALSE; - if (lim_p && lim <= i) break; - } - } - else if (ISSPACE(c)) { - mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg)); - mrb_gc_arena_restore(mrb, ai); - skip = TRUE; - beg = idx; - if (lim_p) ++i; - } - else { - end = idx; - } - } - } - else if (split_type == string) { - mrb_int str_len = RSTRING_LEN(str); - mrb_int pat_len = RSTRING_LEN(spat); - mrb_int idx = 0; - int ai = mrb_gc_arena_save(mrb); - - while (idx < str_len) { - if (pat_len > 0) { - end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx); - if (end < 0) break; - } - else { - end = chars2bytes(str, idx, 1); - } - mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end)); - mrb_gc_arena_restore(mrb, ai); - idx += end + pat_len; - if (lim_p && lim <= ++i) break; - } - beg = idx; - } - else { - mrb_noregexp(mrb, str); - } - if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) { - if (RSTRING_LEN(str) == beg) { - tmp = mrb_str_new_empty(mrb, str); - } - else { - tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg); - } - mrb_ary_push(mrb, result, tmp); - } - if (!lim_p && lim == 0) { - mrb_int len; - while ((len = RARRAY_LEN(result)) > 0 && - (tmp = RARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) == 0)) - mrb_ary_pop(mrb, result); - } - - return result; -} - -MRB_API mrb_value -mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, int base, int badcheck) -{ - const char *p = str; - const char *pend = str + len; - char sign = 1; - int c; - uint64_t n = 0; - mrb_int val; - -#define conv_digit(c) \ - (ISDIGIT(c) ? ((c) - '0') : \ - ISLOWER(c) ? ((c) - 'a' + 10) : \ - ISUPPER(c) ? ((c) - 'A' + 10) : \ - -1) - - if (!p) { - if (badcheck) goto bad; - return mrb_fixnum_value(0); - } - while (p<pend && ISSPACE(*p)) - p++; - - if (p[0] == '+') { - p++; - } - else if (p[0] == '-') { - p++; - sign = 0; - } - if (base <= 0) { - if (p[0] == '0') { - switch (p[1]) { - case 'x': case 'X': - base = 16; - break; - case 'b': case 'B': - base = 2; - break; - case 'o': case 'O': - base = 8; - break; - case 'd': case 'D': - base = 10; - break; - default: - base = 8; - break; - } - } - else if (base < -1) { - base = -base; - } - else { - base = 10; - } - } - switch (base) { - case 2: - if (p[0] == '0' && (p[1] == 'b'||p[1] == 'B')) { - p += 2; - } - break; - case 3: - break; - case 8: - if (p[0] == '0' && (p[1] == 'o'||p[1] == 'O')) { - p += 2; - } - case 4: case 5: case 6: case 7: - break; - case 10: - if (p[0] == '0' && (p[1] == 'd'||p[1] == 'D')) { - p += 2; - } - case 9: case 11: case 12: case 13: case 14: case 15: - break; - case 16: - if (p[0] == '0' && (p[1] == 'x'||p[1] == 'X')) { - p += 2; - } - break; - default: - if (base < 2 || 36 < base) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base)); - } - break; - } /* end of switch (base) { */ - if (p>=pend) { - if (badcheck) goto bad; - return mrb_fixnum_value(0); - } - if (*p == '0') { /* squeeze preceding 0s */ - p++; - while (p<pend) { - c = *p++; - if (c == '_') { - if (p<pend && *p == '_') { - if (badcheck) goto bad; - break; - } - continue; - } - if (c != '0') { - p--; - break; - } - } - if (*(p - 1) == '0') - p--; - } - if (p == pend) { - if (badcheck) goto bad; - return mrb_fixnum_value(0); - } - for ( ;p<pend;p++) { - if (*p == '_') { - p++; - if (p==pend) { - if (badcheck) goto bad; - continue; - } - if (*p == '_') { - if (badcheck) goto bad; - break; - } - } - if (badcheck && *p == '\0') { - goto nullbyte; - } - c = conv_digit(*p); - if (c < 0 || c >= base) { - break; - } - n *= base; - n += c; - if (n > (uint64_t)MRB_INT_MAX + (sign ? 0 : 1)) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", - mrb_str_new(mrb, str, pend-str)); - } - } - val = (mrb_int)n; - if (badcheck) { - if (p == str) goto bad; /* no number */ - while (p<pend && ISSPACE(*p)) p++; - if (p<pend) goto bad; /* trailing garbage */ - } - - return mrb_fixnum_value(sign ? val : -val); - nullbyte: - mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); - /* not reached */ - bad: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)", - mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str))); - /* not reached */ - return mrb_fixnum_value(0); -} - -MRB_API mrb_value -mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) -{ - return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck); -} - -MRB_API const char* -mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) -{ - mrb_value str = mrb_str_to_str(mrb, *ptr); - struct RString *ps = mrb_str_ptr(str); - mrb_int len = mrb_str_strlen(mrb, ps); - char *p = RSTR_PTR(ps); - - if (!p || p[len] != '\0') { - if (MRB_FROZEN_P(ps)) { - *ptr = str = mrb_str_dup(mrb, str); - ps = mrb_str_ptr(str); - } - mrb_str_modify(mrb, ps); - return RSTR_PTR(ps); - } - return p; -} - -MRB_API mrb_value -mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck) -{ - const char *s; - mrb_int len; - - s = mrb_string_value_ptr(mrb, str); - len = RSTRING_LEN(str); - return mrb_str_len_to_inum(mrb, s, len, base, badcheck); -} - -/* 15.2.10.5.38 */ -/* - * call-seq: - * str.to_i(base=10) => integer - * - * Returns the result of interpreting leading characters in <i>str</i> as an - * integer base <i>base</i> (between 2 and 36). Extraneous characters past the - * end of a valid number are ignored. If there is not a valid number at the - * start of <i>str</i>, <code>0</code> is returned. This method never raises an - * exception. - * - * "12345".to_i #=> 12345 - * "99 red balloons".to_i #=> 99 - * "0a".to_i #=> 0 - * "0a".to_i(16) #=> 10 - * "hello".to_i #=> 0 - * "1100101".to_i(2) #=> 101 - * "1100101".to_i(8) #=> 294977 - * "1100101".to_i(10) #=> 1100101 - * "1100101".to_i(16) #=> 17826049 - */ -static mrb_value -mrb_str_to_i(mrb_state *mrb, mrb_value self) -{ - mrb_int base = 10; - - mrb_get_args(mrb, "|i", &base); - if (base < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base)); - } - return mrb_str_to_inum(mrb, self, base, FALSE); -} - -MRB_API double -mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck) -{ - char *end; - char buf[DBL_DIG * 4 + 10]; - double d; - - enum {max_width = 20}; - - if (!p) return 0.0; - while (ISSPACE(*p)) p++; - - if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { - return 0.0; - } - d = mrb_float_read(p, &end); - if (p == end) { - if (badcheck) { -bad: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%S)", mrb_str_new_cstr(mrb, p)); - /* not reached */ - } - return d; - } - if (*end) { - char *n = buf; - char *e = buf + sizeof(buf) - 1; - char prev = 0; - - while (p < end && n < e) prev = *n++ = *p++; - while (*p) { - if (*p == '_') { - /* remove underscores between digits */ - if (badcheck) { - if (n == buf || !ISDIGIT(prev)) goto bad; - ++p; - if (!ISDIGIT(*p)) goto bad; - } - else { - while (*++p == '_'); - continue; - } - } - prev = *p++; - if (n < e) *n++ = prev; - } - *n = '\0'; - p = buf; - - if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { - return 0.0; - } - - d = mrb_float_read(p, &end); - if (badcheck) { - if (!end || p == end) goto bad; - while (*end && ISSPACE(*end)) end++; - if (*end) goto bad; - } - } - return d; -} - -MRB_API double -mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck) -{ - char *s; - mrb_int len; - - str = mrb_str_to_str(mrb, str); - s = RSTRING_PTR(str); - len = RSTRING_LEN(str); - if (s) { - if (badcheck && memchr(s, '\0', len)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte"); - } - if (s[len]) { /* no sentinel somehow */ - struct RString *temp_str = str_new(mrb, s, len); - s = RSTR_PTR(temp_str); - } - } - return mrb_cstr_to_dbl(mrb, s, badcheck); -} - -/* 15.2.10.5.39 */ -/* - * call-seq: - * str.to_f => float - * - * Returns the result of interpreting leading characters in <i>str</i> as a - * floating point number. Extraneous characters past the end of a valid number - * are ignored. If there is not a valid number at the start of <i>str</i>, - * <code>0.0</code> is returned. This method never raises an exception. - * - * "123.45e1".to_f #=> 1234.5 - * "45.67 degrees".to_f #=> 45.67 - * "thx1138".to_f #=> 0.0 - */ -static mrb_value -mrb_str_to_f(mrb_state *mrb, mrb_value self) -{ - return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE)); -} - -/* 15.2.10.5.40 */ -/* - * call-seq: - * str.to_s => str - * str.to_str => str - * - * Returns the receiver. - */ -static mrb_value -mrb_str_to_s(mrb_state *mrb, mrb_value self) -{ - if (mrb_obj_class(mrb, self) != mrb->string_class) { - return mrb_str_dup(mrb, self); - } - return self; -} - -/* 15.2.10.5.43 */ -/* - * call-seq: - * str.upcase! => str or nil - * - * Upcases the contents of <i>str</i>, returning <code>nil</code> if no changes - * were made. - */ -static mrb_value -mrb_str_upcase_bang(mrb_state *mrb, mrb_value str) -{ - struct RString *s = mrb_str_ptr(str); - char *p, *pend; - mrb_bool modify = FALSE; - - mrb_str_modify(mrb, s); - p = RSTRING_PTR(str); - pend = RSTRING_END(str); - while (p < pend) { - if (ISLOWER(*p)) { - *p = TOUPPER(*p); - modify = TRUE; - } - p++; - } - - if (modify) return str; - return mrb_nil_value(); -} - -/* 15.2.10.5.42 */ -/* - * call-seq: - * str.upcase => new_str - * - * Returns a copy of <i>str</i> with all lowercase letters replaced with their - * uppercase counterparts. The operation is locale insensitive---only - * characters 'a' to 'z' are affected. - * - * "hEllO".upcase #=> "HELLO" - */ -static mrb_value -mrb_str_upcase(mrb_state *mrb, mrb_value self) -{ - mrb_value str; - - str = mrb_str_dup(mrb, self); - mrb_str_upcase_bang(mrb, str); - return str; -} - -#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) - -/* - * call-seq: - * str.dump -> new_str - * - * Produces a version of <i>str</i> with all nonprinting characters replaced by - * <code>\nnn</code> notation and all special characters escaped. - */ -mrb_value -mrb_str_dump(mrb_state *mrb, mrb_value str) -{ - mrb_int len; - const char *p, *pend; - char *q; - struct RString *result; - - len = 2; /* "" */ - p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); - while (p < pend) { - unsigned char c = *p++; - switch (c) { - case '"': case '\\': - case '\n': case '\r': - case '\t': case '\f': - case '\013': case '\010': case '\007': case '\033': - len += 2; - break; - - case '#': - len += IS_EVSTR(p, pend) ? 2 : 1; - break; - - default: - if (ISPRINT(c)) { - len++; - } - else { - len += 4; /* \NNN */ - } - break; - } - } - - result = str_new(mrb, 0, len); - str_with_class(mrb, result, str); - p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); - q = RSTR_PTR(result); - *q++ = '"'; - while (p < pend) { - unsigned char c = *p++; - - switch (c) { - case '"': - case '\\': - *q++ = '\\'; - *q++ = c; - break; - - case '\n': - *q++ = '\\'; - *q++ = 'n'; - break; - - case '\r': - *q++ = '\\'; - *q++ = 'r'; - break; - - case '\t': - *q++ = '\\'; - *q++ = 't'; - break; - - case '\f': - *q++ = '\\'; - *q++ = 'f'; - break; - - case '\013': - *q++ = '\\'; - *q++ = 'v'; - break; - - case '\010': - *q++ = '\\'; - *q++ = 'b'; - break; - - case '\007': - *q++ = '\\'; - *q++ = 'a'; - break; - - case '\033': - *q++ = '\\'; - *q++ = 'e'; - break; - - case '#': - if (IS_EVSTR(p, pend)) *q++ = '\\'; - *q++ = '#'; - break; - - default: - if (ISPRINT(c)) { - *q++ = c; - } - else { - *q++ = '\\'; - q[2] = '0' + c % 8; c /= 8; - q[1] = '0' + c % 8; c /= 8; - q[0] = '0' + c % 8; - q += 3; - } - } - } - *q = '"'; - return mrb_obj_value(result); -} - -MRB_API mrb_value -mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len) -{ - struct RString *s = mrb_str_ptr(str); - size_t capa; - size_t total; - ptrdiff_t off = -1; - - if (len == 0) return str; - mrb_str_modify(mrb, s); - if (ptr >= RSTR_PTR(s) && ptr <= RSTR_PTR(s) + (size_t)RSTR_LEN(s)) { - off = ptr - RSTR_PTR(s); - } - - capa = RSTR_CAPA(s); - total = RSTR_LEN(s)+len; - if (total >= MRB_INT_MAX) { - size_error: - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } - if (capa <= total) { - if (capa == 0) capa = 1; - while (capa <= total) { - if (capa <= MRB_INT_MAX / 2) { - capa *= 2; - } - else { - capa = total+1; - } - } - if (capa <= total || capa > MRB_INT_MAX) { - goto size_error; - } - resize_capa(mrb, s, capa); - } - if (off != -1) { - ptr = RSTR_PTR(s) + off; - } - memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len); - mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX); - RSTR_SET_LEN(s, total); - RSTR_PTR(s)[total] = '\0'; /* sentinel */ - return str; -} - -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)); -} - -MRB_API mrb_value -mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2) -{ - return mrb_str_cat(mrb, str, RSTRING_PTR(str2), RSTRING_LEN(str2)); -} - -MRB_API mrb_value -mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) -{ - str2 = mrb_str_to_str(mrb, str2); - return mrb_str_cat_str(mrb, str1, str2); -} - -#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ - -/* - * call-seq: - * str.inspect -> string - * - * Returns a printable version of _str_, surrounded by quote marks, - * with special characters escaped. - * - * str = "hello" - * str[3] = "\b" - * str.inspect #=> "\"hel\\bo\"" - */ -mrb_value -mrb_str_inspect(mrb_state *mrb, mrb_value str) -{ - const char *p, *pend; - char buf[CHAR_ESC_LEN + 1]; - mrb_value result = mrb_str_new_lit(mrb, "\""); - - p = RSTRING_PTR(str); pend = RSTRING_END(str); - for (;p < pend; p++) { - unsigned char c, cc; -#ifdef MRB_UTF8_STRING - mrb_int clen; - - clen = utf8len(p, pend); - if (clen > 1) { - mrb_int i; - - for (i=0; i<clen; i++) { - buf[i] = p[i]; - } - mrb_str_cat(mrb, result, buf, clen); - p += clen-1; - continue; - } -#endif - c = *p; - if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) { - buf[0] = '\\'; buf[1] = c; - mrb_str_cat(mrb, result, buf, 2); - continue; - } - if (ISPRINT(c)) { - buf[0] = c; - mrb_str_cat(mrb, result, buf, 1); - continue; - } - switch (c) { - case '\n': cc = 'n'; break; - case '\r': cc = 'r'; break; - case '\t': cc = 't'; break; - case '\f': cc = 'f'; break; - case '\013': cc = 'v'; break; - case '\010': cc = 'b'; break; - case '\007': cc = 'a'; break; - case 033: cc = 'e'; break; - default: cc = 0; break; - } - if (cc) { - buf[0] = '\\'; - buf[1] = (char)cc; - mrb_str_cat(mrb, result, buf, 2); - continue; - } - else { - buf[0] = '\\'; - buf[3] = '0' + c % 8; c /= 8; - buf[2] = '0' + c % 8; c /= 8; - buf[1] = '0' + c % 8; - mrb_str_cat(mrb, result, buf, 4); - continue; - } - } - mrb_str_cat_lit(mrb, result, "\""); - - return result; -} - -/* - * call-seq: - * str.bytes -> array of fixnums - * - * Returns an array of bytes in _str_. - * - * str = "hello" - * str.bytes #=> [104, 101, 108, 108, 111] - */ -static mrb_value -mrb_str_bytes(mrb_state *mrb, mrb_value str) -{ - struct RString *s = mrb_str_ptr(str); - mrb_value a = mrb_ary_new_capa(mrb, RSTR_LEN(s)); - unsigned char *p = (unsigned char *)(RSTR_PTR(s)), *pend = p + RSTR_LEN(s); - - while (p < pend) { - mrb_ary_push(mrb, a, mrb_fixnum_value(p[0])); - p++; - } - return a; -} - -/* ---------------------------*/ -void -mrb_init_string(mrb_state *mrb) -{ - struct RClass *s; - - mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string"); - - mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class); /* 15.2.10 */ - MRB_SET_INSTANCE_TT(s, MRB_TT_STRING); - - mrb_define_method(mrb, s, "bytesize", mrb_str_bytesize, MRB_ARGS_NONE()); - - mrb_define_method(mrb, s, "<=>", mrb_str_cmp_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.1 */ - mrb_define_method(mrb, s, "==", mrb_str_equal_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.2 */ - mrb_define_method(mrb, s, "+", mrb_str_plus_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */ - mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */ - mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */ - mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */ - mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8 */ - mrb_define_method(mrb, s, "chomp", mrb_str_chomp, MRB_ARGS_ANY()); /* 15.2.10.5.9 */ - mrb_define_method(mrb, s, "chomp!", mrb_str_chomp_bang, MRB_ARGS_ANY()); /* 15.2.10.5.10 */ - mrb_define_method(mrb, s, "chop", mrb_str_chop, MRB_ARGS_NONE()); /* 15.2.10.5.11 */ - mrb_define_method(mrb, s, "chop!", mrb_str_chop_bang, MRB_ARGS_NONE()); /* 15.2.10.5.12 */ - mrb_define_method(mrb, s, "downcase", mrb_str_downcase, MRB_ARGS_NONE()); /* 15.2.10.5.13 */ - mrb_define_method(mrb, s, "downcase!", mrb_str_downcase_bang, MRB_ARGS_NONE()); /* 15.2.10.5.14 */ - mrb_define_method(mrb, s, "empty?", mrb_str_empty_p, MRB_ARGS_NONE()); /* 15.2.10.5.16 */ - mrb_define_method(mrb, s, "eql?", mrb_str_eql, MRB_ARGS_REQ(1)); /* 15.2.10.5.17 */ - - mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_NONE()); /* 15.2.10.5.20 */ - mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */ - mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */ - mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */ - mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */ - mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */ - mrb_define_method(mrb, s, "length", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.26 */ - mrb_define_method(mrb, s, "replace", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.28 */ - mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE()); /* 15.2.10.5.29 */ - mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE()); /* 15.2.10.5.30 */ - mrb_define_method(mrb, s, "rindex", mrb_str_rindex, MRB_ARGS_ANY()); /* 15.2.10.5.31 */ - mrb_define_method(mrb, s, "size", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.33 */ - mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */ - mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */ - - mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.38 */ - mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.39 */ - mrb_define_method(mrb, s, "to_s", mrb_str_to_s, MRB_ARGS_NONE()); /* 15.2.10.5.40 */ - mrb_define_method(mrb, s, "to_str", mrb_str_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "to_sym", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.41 */ - mrb_define_method(mrb, s, "upcase", mrb_str_upcase, MRB_ARGS_NONE()); /* 15.2.10.5.42 */ - mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_NONE()); /* 15.2.10.5.43 */ - mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */ - mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); -} - -/* - * Source code for the "strtod" library procedure. - * - * Copyright (c) 1988-1993 The Regents of the University of California. - * Copyright (c) 1994 Sun Microsystems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies. The University of California - * makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * RCS: @(#) $Id: strtod.c 11708 2007-02-12 23:01:19Z shyouhei $ - */ - -#include <ctype.h> -#include <errno.h> - -static const int maxExponent = 511; /* Largest possible base 10 exponent. Any - * exponent larger than this will already - * produce underflow or overflow, so there's - * no need to worry about additional digits. - */ -static const double powersOf10[] = {/* Table giving binary powers of 10. Entry */ - 10., /* is 10^2^i. Used to convert decimal */ - 100., /* exponents into floating-point numbers. */ - 1.0e4, - 1.0e8, - 1.0e16, - 1.0e32, - 1.0e64, - 1.0e128, - 1.0e256 -}; - -MRB_API double -mrb_float_read(const char *string, char **endPtr) -/* const char *string; A decimal ASCII floating-point number, - * optionally preceded by white space. - * Must have form "-I.FE-X", where I is the - * integer part of the mantissa, F is the - * fractional part of the mantissa, and X - * is the exponent. Either of the signs - * may be "+", "-", or omitted. Either I - * or F may be omitted, or both. The decimal - * point isn't necessary unless F is present. - * The "E" may actually be an "e". E and X - * may both be omitted (but not just one). - */ -/* char **endPtr; If non-NULL, store terminating character's - * address here. */ -{ - int sign, expSign = FALSE; - double fraction, dblExp; - const double *d; - register const char *p; - register int c; - int exp = 0; /* Exponent read from "EX" field. */ - int fracExp = 0; /* Exponent that derives from the fractional - * part. Under normal circumstatnces, it is - * the negative of the number of digits in F. - * However, if I is very long, the last digits - * of I get dropped (otherwise a long I with a - * large negative exponent could cause an - * unnecessary overflow on I alone). In this - * case, fracExp is incremented one for each - * dropped digit. */ - int mantSize; /* Number of digits in mantissa. */ - int decPt; /* Number of mantissa digits BEFORE decimal - * point. */ - const char *pExp; /* Temporarily holds location of exponent - * in string. */ - - /* - * Strip off leading blanks and check for a sign. - */ - - p = string; - while (isspace(*p)) { - p += 1; - } - if (*p == '-') { - sign = TRUE; - p += 1; - } - else { - if (*p == '+') { - p += 1; - } - sign = FALSE; - } - - /* - * Count the number of digits in the mantissa (including the decimal - * point), and also locate the decimal point. - */ - - decPt = -1; - for (mantSize = 0; ; mantSize += 1) - { - c = *p; - if (!isdigit(c)) { - if ((c != '.') || (decPt >= 0)) { - break; - } - decPt = mantSize; - } - p += 1; - } - - /* - * Now suck up the digits in the mantissa. Use two integers to - * collect 9 digits each (this is faster than using floating-point). - * If the mantissa has more than 18 digits, ignore the extras, since - * they can't affect the value anyway. - */ - - pExp = p; - p -= mantSize; - if (decPt < 0) { - decPt = mantSize; - } - else { - mantSize -= 1; /* One of the digits was the point. */ - } - if (mantSize > 18) { - if (decPt - 18 > 29999) { - fracExp = 29999; - } - else { - fracExp = decPt - 18; - } - mantSize = 18; - } - else { - fracExp = decPt - mantSize; - } - if (mantSize == 0) { - fraction = 0.0; - p = string; - goto done; - } - else { - int frac1, frac2; - frac1 = 0; - for ( ; mantSize > 9; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac1 = 10*frac1 + (c - '0'); - } - frac2 = 0; - for (; mantSize > 0; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac2 = 10*frac2 + (c - '0'); - } - fraction = (1.0e9 * frac1) + frac2; - } - - /* - * Skim off the exponent. - */ - - p = pExp; - if ((*p == 'E') || (*p == 'e')) { - p += 1; - if (*p == '-') { - expSign = TRUE; - p += 1; - } - else { - if (*p == '+') { - p += 1; - } - expSign = FALSE; - } - while (isdigit(*p)) { - exp = exp * 10 + (*p - '0'); - if (exp > 19999) { - exp = 19999; - } - p += 1; - } - } - if (expSign) { - exp = fracExp - exp; - } - else { - exp = fracExp + exp; - } - - /* - * Generate a floating-point number that represents the exponent. - * Do this by processing the exponent one bit at a time to combine - * many powers of 2 of 10. Then combine the exponent with the - * fraction. - */ - - if (exp < 0) { - expSign = TRUE; - exp = -exp; - } - else { - expSign = FALSE; - } - if (exp > maxExponent) { - exp = maxExponent; - errno = ERANGE; - } - dblExp = 1.0; - for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { - if (exp & 01) { - dblExp *= *d; - } - } - if (expSign) { - fraction /= dblExp; - } - else { - fraction *= dblExp; - } - -done: - if (endPtr != NULL) { - *endPtr = (char *) p; - } - - if (sign) { - return -fraction; - } - return fraction; -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/symbol.c b/web/server/h2o/libh2o/deps/mruby/src/symbol.c deleted file mode 100644 index a3ab05c85..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/symbol.c +++ /dev/null @@ -1,494 +0,0 @@ -/* -** symbol.c - Symbol class -** -** See Copyright Notice in mruby.h -*/ - -#include <limits.h> -#include <string.h> -#include <mruby.h> -#include <mruby/khash.h> -#include <mruby/string.h> -#include <mruby/dump.h> -#include <mruby/class.h> - -/* ------------------------------------------------------ */ -typedef struct symbol_name { - mrb_bool lit : 1; - uint16_t len; - const char *name; -} symbol_name; - -static inline khint_t -sym_hash_func(mrb_state *mrb, mrb_sym s) -{ - khint_t h = 0; - size_t i, len = mrb->symtbl[s].len; - const char *p = mrb->symtbl[s].name; - - for (i=0; i<len; i++) { - h = (h << 5) - h + *p++; - } - return h; -} -#define sym_hash_equal(mrb,a, b) (mrb->symtbl[a].len == mrb->symtbl[b].len && memcmp(mrb->symtbl[a].name, mrb->symtbl[b].name, mrb->symtbl[a].len) == 0) - -KHASH_DECLARE(n2s, mrb_sym, mrb_sym, FALSE) -KHASH_DEFINE (n2s, mrb_sym, mrb_sym, FALSE, sym_hash_func, sym_hash_equal) -/* ------------------------------------------------------ */ - -static void -sym_validate_len(mrb_state *mrb, size_t len) -{ - if (len >= RITE_LV_NULL_MARK) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long"); - } -} - -static mrb_sym -sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) -{ - khash_t(n2s) *h = mrb->name2sym; - symbol_name *sname = mrb->symtbl; /* symtbl[0] for working memory */ - khiter_t k; - mrb_sym sym; - char *p; - - sym_validate_len(mrb, len); - if (sname) { - sname->lit = lit; - sname->len = (uint16_t)len; - sname->name = name; - k = kh_get(n2s, mrb, h, 0); - if (k != kh_end(h)) - return kh_key(h, k); - } - - /* registering a new symbol */ - sym = ++mrb->symidx; - if (mrb->symcapa < sym) { - if (mrb->symcapa == 0) mrb->symcapa = 100; - else mrb->symcapa = (size_t)(mrb->symcapa * 1.2); - mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1)); - } - sname = &mrb->symtbl[sym]; - sname->len = (uint16_t)len; - if (lit || mrb_ro_data_p(name)) { - sname->name = name; - sname->lit = TRUE; - } - else { - p = (char *)mrb_malloc(mrb, len+1); - memcpy(p, name, len); - p[len] = 0; - sname->name = (const char*)p; - sname->lit = FALSE; - } - kh_put(n2s, mrb, h, sym); - - return sym; -} - -MRB_API mrb_sym -mrb_intern(mrb_state *mrb, const char *name, size_t len) -{ - return sym_intern(mrb, name, len, FALSE); -} - -MRB_API mrb_sym -mrb_intern_static(mrb_state *mrb, const char *name, size_t len) -{ - return sym_intern(mrb, name, len, TRUE); -} - -MRB_API mrb_sym -mrb_intern_cstr(mrb_state *mrb, const char *name) -{ - return mrb_intern(mrb, name, strlen(name)); -} - -MRB_API mrb_sym -mrb_intern_str(mrb_state *mrb, mrb_value str) -{ - return mrb_intern(mrb, RSTRING_PTR(str), RSTRING_LEN(str)); -} - -MRB_API mrb_value -mrb_check_intern(mrb_state *mrb, const char *name, size_t len) -{ - khash_t(n2s) *h = mrb->name2sym; - symbol_name *sname = mrb->symtbl; - khiter_t k; - - sym_validate_len(mrb, len); - sname->len = (uint16_t)len; - sname->name = name; - - k = kh_get(n2s, mrb, h, 0); - if (k != kh_end(h)) { - return mrb_symbol_value(kh_key(h, k)); - } - return mrb_nil_value(); -} - -MRB_API mrb_value -mrb_check_intern_cstr(mrb_state *mrb, const char *name) -{ - return mrb_check_intern(mrb, name, (mrb_int)strlen(name)); -} - -MRB_API mrb_value -mrb_check_intern_str(mrb_state *mrb, mrb_value str) -{ - return mrb_check_intern(mrb, RSTRING_PTR(str), RSTRING_LEN(str)); -} - -/* lenp must be a pointer to a size_t variable */ -MRB_API const char* -mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) -{ - if (sym == 0 || mrb->symidx < sym) { - if (lenp) *lenp = 0; - return NULL; - } - - if (lenp) *lenp = mrb->symtbl[sym].len; - return mrb->symtbl[sym].name; -} - -void -mrb_free_symtbl(mrb_state *mrb) -{ - mrb_sym i, lim; - - for (i=1, lim=mrb->symidx+1; i<lim; i++) { - if (!mrb->symtbl[i].lit) { - mrb_free(mrb, (char*)mrb->symtbl[i].name); - } - } - mrb_free(mrb, mrb->symtbl); - kh_destroy(n2s, mrb, mrb->name2sym); -} - -void -mrb_init_symtbl(mrb_state *mrb) -{ - mrb->name2sym = kh_init(n2s, mrb); -} - -/********************************************************************** - * Document-class: Symbol - * - * <code>Symbol</code> objects represent names and some strings - * inside the Ruby - * interpreter. They are generated using the <code>:name</code> and - * <code>:"string"</code> literals - * syntax, and by the various <code>to_sym</code> methods. The same - * <code>Symbol</code> object will be created for a given name or string - * for the duration of a program's execution, regardless of the context - * or meaning of that name. Thus if <code>Fred</code> is a constant in - * one context, a method in another, and a class in a third, the - * <code>Symbol</code> <code>:Fred</code> will be the same object in - * all three contexts. - * - * module One - * class Fred - * end - * $f1 = :Fred - * end - * module Two - * Fred = 1 - * $f2 = :Fred - * end - * def Fred() - * end - * $f3 = :Fred - * $f1.object_id #=> 2514190 - * $f2.object_id #=> 2514190 - * $f3.object_id #=> 2514190 - * - */ - - -/* 15.2.11.3.1 */ -/* - * call-seq: - * sym == obj -> true or false - * - * Equality---If <i>sym</i> and <i>obj</i> are exactly the same - * symbol, returns <code>true</code>. - */ - -static mrb_value -sym_equal(mrb_state *mrb, mrb_value sym1) -{ - mrb_value sym2; - - mrb_get_args(mrb, "o", &sym2); - - return mrb_bool_value(mrb_obj_equal(mrb, sym1, sym2)); -} - -/* 15.2.11.3.2 */ -/* 15.2.11.3.3 */ -/* - * call-seq: - * sym.id2name -> string - * sym.to_s -> string - * - * Returns the name or string corresponding to <i>sym</i>. - * - * :fred.id2name #=> "fred" - */ -static mrb_value -mrb_sym_to_s(mrb_state *mrb, mrb_value sym) -{ - mrb_sym id = mrb_symbol(sym); - const char *p; - mrb_int len; - - p = mrb_sym2name_len(mrb, id, &len); - return mrb_str_new_static(mrb, p, len); -} - -/* 15.2.11.3.4 */ -/* - * call-seq: - * sym.to_sym -> sym - * sym.intern -> sym - * - * In general, <code>to_sym</code> returns the <code>Symbol</code> corresponding - * to an object. As <i>sym</i> is already a symbol, <code>self</code> is returned - * in this case. - */ - -static mrb_value -sym_to_sym(mrb_state *mrb, mrb_value sym) -{ - return sym; -} - -/* 15.2.11.3.5(x) */ -/* - * call-seq: - * sym.inspect -> string - * - * Returns the representation of <i>sym</i> as a symbol literal. - * - * :fred.inspect #=> ":fred" - */ - -#if __STDC__ -# define SIGN_EXTEND_CHAR(c) ((signed char)(c)) -#else /* not __STDC__ */ -/* As in Harbison and Steele. */ -# define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128) -#endif -#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_')) - -static mrb_bool -is_special_global_name(const char* m) -{ - switch (*m) { - case '~': case '*': case '$': case '?': case '!': case '@': - case '/': case '\\': case ';': case ',': case '.': case '=': - case ':': case '<': case '>': case '\"': - case '&': case '`': case '\'': case '+': - case '0': - ++m; - break; - case '-': - ++m; - if (is_identchar(*m)) m += 1; - break; - default: - if (!ISDIGIT(*m)) return FALSE; - do ++m; while (ISDIGIT(*m)); - break; - } - return !*m; -} - -static mrb_bool -symname_p(const char *name) -{ - const char *m = name; - mrb_bool localid = FALSE; - - if (!m) return FALSE; - switch (*m) { - case '\0': - return FALSE; - - case '$': - if (is_special_global_name(++m)) return TRUE; - goto id; - - case '@': - if (*++m == '@') ++m; - goto id; - - case '<': - switch (*++m) { - case '<': ++m; break; - case '=': if (*++m == '>') ++m; break; - default: break; - } - break; - - case '>': - switch (*++m) { - case '>': case '=': ++m; break; - default: break; - } - break; - - case '=': - switch (*++m) { - case '~': ++m; break; - case '=': if (*++m == '=') ++m; break; - default: return FALSE; - } - break; - - case '*': - if (*++m == '*') ++m; - break; - case '!': - switch (*++m) { - case '=': case '~': ++m; - } - break; - case '+': case '-': - if (*++m == '@') ++m; - break; - case '|': - if (*++m == '|') ++m; - break; - case '&': - if (*++m == '&') ++m; - break; - - case '^': case '/': case '%': case '~': case '`': - ++m; - break; - - case '[': - if (*++m != ']') return FALSE; - if (*++m == '=') ++m; - break; - - default: - localid = !ISUPPER(*m); -id: - if (*m != '_' && !ISALPHA(*m)) return FALSE; - while (is_identchar(*m)) m += 1; - if (localid) { - switch (*m) { - case '!': case '?': case '=': ++m; - default: break; - } - } - break; - } - return *m ? FALSE : TRUE; -} - -static mrb_value -sym_inspect(mrb_state *mrb, mrb_value sym) -{ - mrb_value str; - const char *name; - mrb_int len; - mrb_sym id = mrb_symbol(sym); - char *sp; - - name = mrb_sym2name_len(mrb, id, &len); - str = mrb_str_new(mrb, 0, len+1); - sp = RSTRING_PTR(str); - RSTRING_PTR(str)[0] = ':'; - memcpy(sp+1, name, len); - mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); - if (!symname_p(name) || strlen(name) != (size_t)len) { - str = mrb_str_dump(mrb, str); - sp = RSTRING_PTR(str); - sp[0] = ':'; - sp[1] = '"'; - } - return str; -} - -MRB_API mrb_value -mrb_sym2str(mrb_state *mrb, mrb_sym sym) -{ - mrb_int len; - const char *name = mrb_sym2name_len(mrb, sym, &len); - - if (!name) return mrb_undef_value(); /* can't happen */ - return mrb_str_new_static(mrb, name, len); -} - -MRB_API const char* -mrb_sym2name(mrb_state *mrb, mrb_sym sym) -{ - mrb_int len; - const char *name = mrb_sym2name_len(mrb, sym, &len); - - if (!name) return NULL; - if (symname_p(name) && strlen(name) == (size_t)len) { - return name; - } - else { - mrb_value str = mrb_str_dump(mrb, mrb_str_new_static(mrb, name, len)); - return RSTRING_PTR(str); - } -} - -#define lesser(a,b) (((a)>(b))?(b):(a)) - -static mrb_value -sym_cmp(mrb_state *mrb, mrb_value s1) -{ - mrb_value s2; - mrb_sym sym1, sym2; - - mrb_get_args(mrb, "o", &s2); - if (mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value(); - sym1 = mrb_symbol(s1); - sym2 = mrb_symbol(s2); - if (sym1 == sym2) return mrb_fixnum_value(0); - else { - const char *p1, *p2; - int retval; - mrb_int len, len1, len2; - - p1 = mrb_sym2name_len(mrb, sym1, &len1); - p2 = mrb_sym2name_len(mrb, sym2, &len2); - len = lesser(len1, len2); - retval = memcmp(p1, p2, len); - if (retval == 0) { - if (len1 == len2) return mrb_fixnum_value(0); - if (len1 > len2) return mrb_fixnum_value(1); - return mrb_fixnum_value(-1); - } - if (retval > 0) return mrb_fixnum_value(1); - return mrb_fixnum_value(-1); - } -} - -void -mrb_init_symbol(mrb_state *mrb) -{ - struct RClass *sym; - - mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class); /* 15.2.11 */ - MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL); - mrb_undef_class_method(mrb, sym, "new"); - - mrb_define_method(mrb, sym, "===", sym_equal, MRB_ARGS_REQ(1)); /* 15.2.11.3.1 */ - mrb_define_method(mrb, sym, "id2name", mrb_sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.2 */ - mrb_define_method(mrb, sym, "to_s", mrb_sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.3 */ - mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */ - mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */ - mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1)); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/value_array.h b/web/server/h2o/libh2o/deps/mruby/src/value_array.h deleted file mode 100644 index bc5f28b06..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/value_array.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef MRB_VALUE_ARRAY_H__ -#define MRB_VALUE_ARRAY_H__ - -#include <mruby.h> - -static inline void -value_move(mrb_value *s1, const mrb_value *s2, size_t n) -{ - if (s1 > s2 && s1 < s2 + n) - { - s1 += n; - s2 += n; - while (n-- > 0) { - *--s1 = *--s2; - } - } - else if (s1 != s2) { - while (n-- > 0) { - *s1++ = *s2++; - } - } - else { - /* nothing to do. */ - } -} - -#endif /* MRB_VALUE_ARRAY_H__ */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/variable.c b/web/server/h2o/libh2o/deps/mruby/src/variable.c deleted file mode 100644 index 50fc70682..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/variable.c +++ /dev/null @@ -1,987 +0,0 @@ -/* -** variable.c - mruby variables -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/proc.h> -#include <mruby/string.h> - -typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*); - -#include <mruby/khash.h> - -#ifndef MRB_IVHASH_INIT_SIZE -#define MRB_IVHASH_INIT_SIZE KHASH_MIN_SIZE -#endif - -KHASH_DECLARE(iv, mrb_sym, mrb_value, TRUE) -KHASH_DEFINE(iv, mrb_sym, mrb_value, TRUE, kh_int_hash_func, kh_int_hash_equal) - -/* Instance variable table structure */ -typedef struct iv_tbl { - khash_t(iv) h; -} iv_tbl; - -/* - * Creates the instance variable table. - * - * Parameters - * mrb - * Returns - * the instance variable table. - */ -static iv_tbl* -iv_new(mrb_state *mrb) -{ - return (iv_tbl*)kh_init_size(iv, mrb, MRB_IVHASH_INIT_SIZE); -} - -/* - * Set the value for the symbol in the instance variable table. - * - * Parameters - * mrb - * t the instance variable table to be set in. - * sym the symbol to be used as the key. - * val the value to be set. - */ -static void -iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) -{ - khash_t(iv) *h = &t->h; - khiter_t k; - - k = kh_put(iv, mrb, h, sym); - kh_value(h, k) = val; -} - -/* - * Get a value for a symbol from the instance variable table. - * - * Parameters - * mrb - * t the variable table to be searched. - * sym the symbol to be used as the key. - * vp the value pointer. Receives the value if the specified symbol is - * contained in the instance variable table. - * Returns - * true if the specified symbol is contained in the instance variable table. - */ -static mrb_bool -iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) -{ - khash_t(iv) *h = &t->h; - khiter_t k; - - k = kh_get(iv, mrb, h, sym); - if (k != kh_end(h)) { - if (vp) *vp = kh_value(h, k); - return TRUE; - } - return FALSE; -} - -/* - * Deletes the value for the symbol from the instance variable table. - * - * Parameters - * t the variable table to be searched. - * sym the symbol to be used as the key. - * vp the value pointer. Receive the deleted value if the symbol is - * contained in the instance variable table. - * Returns - * true if the specified symbol is contained in the instance variable table. - */ -static mrb_bool -iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) -{ - if (t == NULL) return FALSE; - else { - khash_t(iv) *h = &t->h; - khiter_t k; - - k = kh_get(iv, mrb, h, sym); - if (k != kh_end(h)) { - mrb_value val = kh_value(h, k); - kh_del(iv, mrb, h, k); - if (vp) *vp = val; - return TRUE; - } - } - return FALSE; -} - -static mrb_bool -iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p) -{ - if (t == NULL) { - return TRUE; - } - else { - khash_t(iv) *h = &t->h; - khiter_t k; - int n; - - for (k = kh_begin(h); k != kh_end(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) { - kh_del(iv, mrb, h, k); - } - } - } - } - return TRUE; -} - -static size_t -iv_size(mrb_state *mrb, iv_tbl *t) -{ - if (t) { - return kh_size(&t->h); - } - return 0; -} - -static iv_tbl* -iv_copy(mrb_state *mrb, iv_tbl *t) -{ - return (iv_tbl*)kh_copy(iv, mrb, &t->h); -} - -static void -iv_free(mrb_state *mrb, iv_tbl *t) -{ - kh_destroy(iv, mrb, &t->h); -} - -static int -iv_mark_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) -{ - mrb_gc_mark_value(mrb, v); - return 0; -} - -static void -mark_tbl(mrb_state *mrb, iv_tbl *t) -{ - if (t) { - iv_foreach(mrb, t, iv_mark_i, 0); - } -} - -void -mrb_gc_mark_gv(mrb_state *mrb) -{ - mark_tbl(mrb, mrb->globals); -} - -void -mrb_gc_free_gv(mrb_state *mrb) -{ - if (mrb->globals) - iv_free(mrb, mrb->globals); -} - -void -mrb_gc_mark_iv(mrb_state *mrb, struct RObject *obj) -{ - mark_tbl(mrb, obj->iv); -} - -size_t -mrb_gc_mark_iv_size(mrb_state *mrb, struct RObject *obj) -{ - return iv_size(mrb, obj->iv); -} - -void -mrb_gc_free_iv(mrb_state *mrb, struct RObject *obj) -{ - if (obj->iv) { - iv_free(mrb, obj->iv); - } -} - -mrb_value -mrb_vm_special_get(mrb_state *mrb, mrb_sym i) -{ - return mrb_fixnum_value(0); -} - -void -mrb_vm_special_set(mrb_state *mrb, mrb_sym i, mrb_value v) -{ -} - -static mrb_bool -obj_iv_p(mrb_value obj) -{ - switch (mrb_type(obj)) { - case MRB_TT_OBJECT: - case MRB_TT_CLASS: - case MRB_TT_MODULE: - case MRB_TT_SCLASS: - case MRB_TT_HASH: - case MRB_TT_DATA: - case MRB_TT_EXCEPTION: - return TRUE; - default: - return FALSE; - } -} - -MRB_API mrb_value -mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym) -{ - mrb_value v; - - if (obj->iv && iv_get(mrb, obj->iv, sym, &v)) - return v; - return mrb_nil_value(); -} - -MRB_API mrb_value -mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym) -{ - if (obj_iv_p(obj)) { - return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym); - } - return mrb_nil_value(); -} - -MRB_API void -mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) -{ - iv_tbl *t = obj->iv; - - if (MRB_FROZEN_P(obj)) { - mrb_raisef(mrb, E_RUNTIME_ERROR, "can't modify frozen %S", mrb_obj_value(obj)); - } - if (!t) { - t = obj->iv = iv_new(mrb); - } - mrb_write_barrier(mrb, (struct RBasic*)obj); - iv_put(mrb, t, sym, v); -} - -MRB_API void -mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) -{ - if (obj_iv_p(obj)) { - mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), sym, v); - } - else { - mrb_raise(mrb, E_ARGUMENT_ERROR, "cannot set instance variable"); - } -} - -MRB_API mrb_bool -mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym) -{ - iv_tbl *t; - - t = obj->iv; - if (t) { - return iv_get(mrb, t, sym, NULL); - } - return FALSE; -} - -MRB_API mrb_bool -mrb_iv_defined(mrb_state *mrb, mrb_value obj, mrb_sym sym) -{ - if (!obj_iv_p(obj)) return FALSE; - return mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), sym); -} - -#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) - -MRB_API mrb_bool -mrb_iv_p(mrb_state *mrb, mrb_sym iv_name) -{ - const char *s; - mrb_int i, len; - - s = mrb_sym2name_len(mrb, iv_name, &len); - if (len < 2) return FALSE; - if (s[0] != '@') return FALSE; - if (s[1] == '@') return FALSE; - for (i=1; i<len; i++) { - if (!identchar(s[i])) return FALSE; - } - return TRUE; -} - -MRB_API void -mrb_iv_check(mrb_state *mrb, mrb_sym iv_name) -{ - if (!mrb_iv_p(mrb, iv_name)) { - mrb_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name)); - } -} - -MRB_API void -mrb_iv_copy(mrb_state *mrb, mrb_value dest, mrb_value src) -{ - struct RObject *d = mrb_obj_ptr(dest); - struct RObject *s = mrb_obj_ptr(src); - - if (d->iv) { - iv_free(mrb, d->iv); - d->iv = 0; - } - if (s->iv) { - mrb_write_barrier(mrb, (struct RBasic*)d); - d->iv = iv_copy(mrb, s->iv); - } -} - -static int -inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) -{ - mrb_value str = *(mrb_value*)p; - const char *s; - mrb_int len; - mrb_value ins; - char *sp = RSTRING_PTR(str); - - /* need not to show internal data */ - if (sp[0] == '-') { /* first element */ - sp[0] = '#'; - mrb_str_cat_lit(mrb, str, " "); - } - else { - mrb_str_cat_lit(mrb, str, ", "); - } - s = mrb_sym2name_len(mrb, sym, &len); - mrb_str_cat(mrb, str, s, len); - mrb_str_cat_lit(mrb, str, "="); - if (mrb_type(v) == MRB_TT_OBJECT) { - ins = mrb_any_to_s(mrb, v); - } - else { - ins = mrb_inspect(mrb, v); - } - mrb_str_cat_str(mrb, str, ins); - return 0; -} - -mrb_value -mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) -{ - iv_tbl *t = obj->iv; - size_t len = iv_size(mrb, t); - - if (len > 0) { - const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj)); - mrb_value str = mrb_str_new_capa(mrb, 30); - - mrb_str_cat_lit(mrb, str, "-<"); - mrb_str_cat_cstr(mrb, str, cn); - mrb_str_cat_lit(mrb, str, ":"); - mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj)); - - iv_foreach(mrb, t, inspect_i, &str); - mrb_str_cat_lit(mrb, str, ">"); - return str; - } - return mrb_any_to_s(mrb, mrb_obj_value(obj)); -} - -MRB_API mrb_value -mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym) -{ - if (obj_iv_p(obj)) { - iv_tbl *t = mrb_obj_ptr(obj)->iv; - mrb_value val; - - if (t && iv_del(mrb, t, sym, &val)) { - return val; - } - } - return mrb_undef_value(); -} - -mrb_value -mrb_vm_iv_get(mrb_state *mrb, mrb_sym sym) -{ - /* get self */ - return mrb_iv_get(mrb, mrb->c->stack[0], sym); -} - -void -mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) -{ - /* get self */ - mrb_iv_set(mrb, mrb->c->stack[0], sym, v); -} - -static int -iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) -{ - mrb_value ary; - const char* s; - mrb_int len; - - ary = *(mrb_value*)p; - s = mrb_sym2name_len(mrb, sym, &len); - if (len > 1 && s[0] == '@' && s[1] != '@') { - mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); - } - return 0; -} - -/* 15.3.1.3.23 */ -/* - * call-seq: - * obj.instance_variables -> array - * - * Returns an array of instance variable names for the receiver. Note - * that simply defining an accessor does not create the corresponding - * instance variable. - * - * class Fred - * attr_accessor :a1 - * def initialize - * @iv = 3 - * end - * end - * Fred.new.instance_variables #=> [:@iv] - */ -mrb_value -mrb_obj_instance_variables(mrb_state *mrb, mrb_value self) -{ - mrb_value ary; - - ary = mrb_ary_new(mrb); - if (obj_iv_p(self) && mrb_obj_ptr(self)->iv) { - iv_foreach(mrb, mrb_obj_ptr(self)->iv, iv_i, &ary); - } - return ary; -} - -static int -cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) -{ - mrb_value ary; - const char* s; - mrb_int len; - - ary = *(mrb_value*)p; - s = mrb_sym2name_len(mrb, sym, &len); - if (len > 2 && s[0] == '@' && s[1] == '@') { - mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); - } - return 0; -} - -/* 15.2.2.4.19 */ -/* - * call-seq: - * mod.class_variables -> array - * - * Returns an array of the names of class variables in <i>mod</i>. - * - * class One - * @@var1 = 1 - * end - * class Two < One - * @@var2 = 2 - * end - * One.class_variables #=> [:@@var1] - * Two.class_variables #=> [:@@var2] - */ -mrb_value -mrb_mod_class_variables(mrb_state *mrb, mrb_value mod) -{ - mrb_value ary; - struct RClass *c; - - ary = mrb_ary_new(mrb); - c = mrb_class_ptr(mod); - while (c) { - if (c->iv) { - iv_foreach(mrb, c->iv, cv_i, &ary); - } - c = c->super; - } - return ary; -} - -MRB_API mrb_value -mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym) -{ - struct RClass * cls = c; - mrb_value v; - int given = FALSE; - - while (c) { - if (c->iv && iv_get(mrb, c->iv, sym, &v)) { - given = TRUE; - } - c = c->super; - } - if (given) return v; - if (cls && cls->tt == MRB_TT_SCLASS) { - mrb_value klass; - - klass = mrb_obj_iv_get(mrb, (struct RObject *)cls, - mrb_intern_lit(mrb, "__attached__")); - c = mrb_class_ptr(klass); - if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) { - given = FALSE; - while (c) { - if (c->iv && iv_get(mrb, c->iv, sym, &v)) { - given = TRUE; - } - c = c->super; - } - if (given) return v; - } - } - mrb_name_error(mrb, sym, "uninitialized class variable %S in %S", - mrb_sym2str(mrb, sym), mrb_obj_value(cls)); - /* not reached */ - return mrb_nil_value(); -} - -MRB_API mrb_value -mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) -{ - return mrb_mod_cv_get(mrb, mrb_class_ptr(mod), sym); -} - -MRB_API void -mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v) -{ - struct RClass * cls = c; - - while (c) { - if (c->iv) { - iv_tbl *t = c->iv; - - if (iv_get(mrb, t, sym, NULL)) { - mrb_write_barrier(mrb, (struct RBasic*)c); - iv_put(mrb, t, sym, v); - return; - } - } - c = c->super; - } - - if (cls && cls->tt == MRB_TT_SCLASS) { - mrb_value klass; - - klass = mrb_obj_iv_get(mrb, (struct RObject*)cls, - mrb_intern_lit(mrb, "__attached__")); - switch (mrb_type(klass)) { - case MRB_TT_CLASS: - case MRB_TT_MODULE: - case MRB_TT_SCLASS: - c = mrb_class_ptr(klass); - break; - default: - c = cls; - break; - } - } - else{ - c = cls; - } - - if (!c->iv) { - c->iv = iv_new(mrb); - } - - mrb_write_barrier(mrb, (struct RBasic*)c); - iv_put(mrb, c->iv, sym, v); -} - -MRB_API void -mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) -{ - mrb_mod_cv_set(mrb, mrb_class_ptr(mod), sym, v); -} - -MRB_API mrb_bool -mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym) -{ - while (c) { - if (c->iv) { - iv_tbl *t = c->iv; - if (iv_get(mrb, t, sym, NULL)) return TRUE; - } - c = c->super; - } - - return FALSE; -} - -MRB_API mrb_bool -mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym) -{ - return mrb_mod_cv_defined(mrb, mrb_class_ptr(mod), sym); -} - -mrb_value -mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) -{ - struct RClass *c = mrb->c->ci->proc->target_class; - - if (!c) c = mrb->c->ci->target_class; - - return mrb_mod_cv_get(mrb, c, sym); -} - -void -mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) -{ - struct RClass *c = mrb->c->ci->proc->target_class; - - if (!c) c = mrb->c->ci->target_class; - mrb_mod_cv_set(mrb, c, sym, v); -} - -static void -mod_const_check(mrb_state *mrb, mrb_value mod) -{ - switch (mrb_type(mod)) { - case MRB_TT_CLASS: - case MRB_TT_MODULE: - case MRB_TT_SCLASS: - break; - default: - mrb_raise(mrb, E_TYPE_ERROR, "constant look-up for non class/module"); - break; - } -} - -static mrb_value -const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) -{ - struct RClass *c = base; - mrb_value v; - iv_tbl *t; - mrb_bool retry = FALSE; - mrb_value name; - -L_RETRY: - while (c) { - if (c->iv) { - t = c->iv; - if (iv_get(mrb, t, sym, &v)) - return v; - } - c = c->super; - } - if (!retry && base && base->tt == MRB_TT_MODULE) { - c = mrb->object_class; - retry = TRUE; - goto L_RETRY; - } - name = mrb_symbol_value(sym); - return mrb_funcall_argv(mrb, mrb_obj_value(base), mrb_intern_lit(mrb, "const_missing"), 1, &name); -} - -MRB_API mrb_value -mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) -{ - mod_const_check(mrb, mod); - return const_get(mrb, mrb_class_ptr(mod), sym); -} - -mrb_value -mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) -{ - struct RClass *c = mrb->c->ci->proc->target_class; - struct RClass *c2; - mrb_value v; - mrb_irep *irep; - - if (!c) c = mrb->c->ci->target_class; - mrb_assert(c != NULL); - - if (c->iv && iv_get(mrb, c->iv, sym, &v)) { - return v; - } - c2 = c; - while (c2 && c2->tt == MRB_TT_SCLASS) { - mrb_value klass; - klass = mrb_obj_iv_get(mrb, (struct RObject *)c2, - mrb_intern_lit(mrb, "__attached__")); - c2 = mrb_class_ptr(klass); - } - if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2; - mrb_assert(!MRB_PROC_CFUNC_P(mrb->c->ci->proc)); - irep = mrb->c->ci->proc->body.irep; - while (irep) { - if (irep->target_class) { - c2 = irep->target_class; - if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) { - return v; - } - } - irep = irep->outer; - } - return const_get(mrb, c, sym); -} - -MRB_API void -mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) -{ - mod_const_check(mrb, mod); - if (mrb_type(v) == MRB_TT_CLASS || mrb_type(v) == MRB_TT_MODULE) { - mrb_class_name_class(mrb, mrb_class_ptr(mod), mrb_class_ptr(v), sym); - } - mrb_iv_set(mrb, mod, sym, v); -} - -void -mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) -{ - struct RClass *c = mrb->c->ci->proc->target_class; - - if (!c) c = mrb->c->ci->target_class; - mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v); -} - -MRB_API void -mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym) -{ - mod_const_check(mrb, mod); - mrb_iv_remove(mrb, mod, sym); -} - -MRB_API void -mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v) -{ - mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern_cstr(mrb, name), v); -} - -MRB_API void -mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val) -{ - mrb_define_const(mrb, mrb->object_class, name, val); -} - -static int -const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) -{ - mrb_value ary; - const char* s; - mrb_int len; - - ary = *(mrb_value*)p; - s = mrb_sym2name_len(mrb, sym, &len); - if (len >= 1 && ISUPPER(s[0])) { - mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); - } - return 0; -} - -/* 15.2.2.4.24 */ -/* - * call-seq: - * mod.constants -> array - * - * Returns an array of all names of contants defined in the receiver. - */ -mrb_value -mrb_mod_constants(mrb_state *mrb, mrb_value mod) -{ - mrb_value ary; - mrb_bool inherit = TRUE; - struct RClass *c = mrb_class_ptr(mod); - - mrb_get_args(mrb, "|b", &inherit); - ary = mrb_ary_new(mrb); - while (c) { - if (c->iv) { - iv_foreach(mrb, c->iv, const_i, &ary); - } - if (!inherit) break; - c = c->super; - if (c == mrb->object_class) break; - } - return ary; -} - -MRB_API mrb_value -mrb_gv_get(mrb_state *mrb, mrb_sym sym) -{ - mrb_value v; - - if (!mrb->globals) { - return mrb_nil_value(); - } - if (iv_get(mrb, mrb->globals, sym, &v)) - return v; - return mrb_nil_value(); -} - -MRB_API void -mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) -{ - iv_tbl *t; - - if (!mrb->globals) { - t = mrb->globals = iv_new(mrb); - } - else { - t = mrb->globals; - } - iv_put(mrb, t, sym, v); -} - -MRB_API void -mrb_gv_remove(mrb_state *mrb, mrb_sym sym) -{ - if (!mrb->globals) { - return; - } - iv_del(mrb, mrb->globals, sym, NULL); -} - -static int -gv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) -{ - mrb_value ary; - - ary = *(mrb_value*)p; - mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); - return 0; -} - -/* 15.3.1.2.4 */ -/* 15.3.1.3.14 */ -/* - * call-seq: - * global_variables -> array - * - * Returns an array of the names of global variables. - * - * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr] - */ -mrb_value -mrb_f_global_variables(mrb_state *mrb, mrb_value self) -{ - iv_tbl *t = mrb->globals; - mrb_value ary = mrb_ary_new(mrb); - size_t i; - char buf[3]; - - if (t) { - iv_foreach(mrb, t, gv_i, &ary); - } - buf[0] = '$'; - buf[2] = 0; - for (i = 1; i <= 9; ++i) { - buf[1] = (char)(i + '0'); - mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2))); - } - return ary; -} - -static mrb_bool -mrb_const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb_bool recurse) -{ - struct RClass *klass = mrb_class_ptr(mod); - struct RClass *tmp; - mrb_bool mod_retry = 0; - - tmp = klass; -retry: - while (tmp) { - if (tmp->iv && iv_get(mrb, tmp->iv, id, NULL)) { - return TRUE; - } - if (!recurse && (klass != mrb->object_class)) break; - tmp = tmp->super; - } - if (!exclude && !mod_retry && (klass->tt == MRB_TT_MODULE)) { - mod_retry = 1; - tmp = mrb->object_class; - goto retry; - } - return FALSE; -} - -MRB_API mrb_bool -mrb_const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id) -{ - return mrb_const_defined_0(mrb, mod, id, TRUE, TRUE); -} - -MRB_API mrb_bool -mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id) -{ - return mrb_const_defined_0(mrb, mod, id, TRUE, FALSE); -} - -MRB_API mrb_value -mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id) -{ - return mrb_iv_get(mrb, obj, id); -} - -struct csym_arg { - struct RClass *c; - mrb_sym sym; -}; - -static int -csym_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) -{ - struct csym_arg *a = (struct csym_arg*)p; - struct RClass *c = a->c; - - if (mrb_type(v) == c->tt && mrb_class_ptr(v) == c) { - a->sym = sym; - return 1; /* stop iteration */ - } - return 0; -} - -static mrb_sym -find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c) -{ - struct csym_arg arg; - - if (!outer) return 0; - arg.c = c; - arg.sym = 0; - iv_foreach(mrb, outer->iv, csym_i, &arg); - return arg.sym; -} - -mrb_value -mrb_class_find_path(mrb_state *mrb, struct RClass *c) -{ - mrb_value outer, path; - mrb_sym name; - const char *str; - mrb_int len; - mrb_sym osym = mrb_intern_lit(mrb, "__outer__"); - - outer = mrb_obj_iv_get(mrb, (struct RObject*)c, osym); - if (mrb_nil_p(outer)) return outer; - name = find_class_sym(mrb, mrb_class_ptr(outer), c); - if (name == 0) return mrb_nil_value(); - str = mrb_class_name(mrb, mrb_class_ptr(outer)); - path = mrb_str_new_capa(mrb, 40); - mrb_str_cat_cstr(mrb, path, str); - mrb_str_cat_cstr(mrb, path, "::"); - - str = mrb_sym2name_len(mrb, name, &len); - mrb_str_cat(mrb, path, str, len); - iv_del(mrb, c->iv, osym, NULL); - iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path); - mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path); - return path; -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/version.c b/web/server/h2o/libh2o/deps/mruby/src/version.c deleted file mode 100644 index 350bc1673..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/version.c +++ /dev/null @@ -1,17 +0,0 @@ -#include <mruby.h> -#include <mruby/variable.h> - -void -mrb_init_version(mrb_state* mrb) -{ - mrb_value mruby_version = mrb_str_new_lit(mrb, MRUBY_VERSION); - - mrb_define_global_const(mrb, "RUBY_VERSION", mrb_str_new_lit(mrb, MRUBY_RUBY_VERSION)); - mrb_define_global_const(mrb, "RUBY_ENGINE", mrb_str_new_lit(mrb, MRUBY_RUBY_ENGINE)); - mrb_define_global_const(mrb, "RUBY_ENGINE_VERSION", mruby_version); - mrb_define_global_const(mrb, "MRUBY_VERSION", mruby_version); - mrb_define_global_const(mrb, "MRUBY_RELEASE_NO", mrb_fixnum_value(MRUBY_RELEASE_NO)); - mrb_define_global_const(mrb, "MRUBY_RELEASE_DATE", mrb_str_new_lit(mrb, MRUBY_RELEASE_DATE)); - mrb_define_global_const(mrb, "MRUBY_DESCRIPTION", mrb_str_new_lit(mrb, MRUBY_DESCRIPTION)); - mrb_define_global_const(mrb, "MRUBY_COPYRIGHT", mrb_str_new_lit(mrb, MRUBY_COPYRIGHT)); -} diff --git a/web/server/h2o/libh2o/deps/mruby/src/vm.c b/web/server/h2o/libh2o/deps/mruby/src/vm.c deleted file mode 100644 index f413211e7..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/vm.c +++ /dev/null @@ -1,2909 +0,0 @@ -/* -** vm.c - virtual machine for mruby -** -** See Copyright Notice in mruby.h -*/ - -#include <stddef.h> -#include <stdarg.h> -#include <math.h> -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/hash.h> -#include <mruby/irep.h> -#include <mruby/numeric.h> -#include <mruby/proc.h> -#include <mruby/range.h> -#include <mruby/string.h> -#include <mruby/variable.h> -#include <mruby/error.h> -#include <mruby/opcode.h> -#include "value_array.h" -#include <mruby/throw.h> - -#ifdef MRB_DISABLE_STDIO -#if defined(__cplusplus) -extern "C" { -#endif -void abort(void); -#if defined(__cplusplus) -} /* extern "C" { */ -#endif -#endif - -#define STACK_INIT_SIZE 128 -#define CALLINFO_INIT_SIZE 32 - -#ifndef ENSURE_STACK_INIT_SIZE -#define ENSURE_STACK_INIT_SIZE 16 -#endif - -#ifndef RESCUE_STACK_INIT_SIZE -#define RESCUE_STACK_INIT_SIZE 16 -#endif - -/* Define amount of linear stack growth. */ -#ifndef MRB_STACK_GROWTH -#define MRB_STACK_GROWTH 128 -#endif - -/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */ -#ifndef MRB_FUNCALL_DEPTH_MAX -#define MRB_FUNCALL_DEPTH_MAX 512 -#endif - -/* Maximum stack depth. Should be set lower on memory constrained systems. -The value below allows about 60000 recursive calls in the simplest case. */ -#ifndef MRB_STACK_MAX -#define MRB_STACK_MAX (0x40000 - MRB_STACK_GROWTH) -#endif - -#ifdef VM_DEBUG -# define DEBUG(x) (x) -#else -# define DEBUG(x) -#endif - - -#ifndef MRB_GC_FIXED_ARENA -static void -mrb_gc_arena_shrink(mrb_state *mrb, int idx) -{ - mrb_gc *gc = &mrb->gc; - int capa = gc->arena_capa; - - if (idx < capa / 4) { - capa >>= 2; - if (capa < MRB_GC_ARENA_SIZE) { - capa = MRB_GC_ARENA_SIZE; - } - if (capa != gc->arena_capa) { - gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa); - gc->arena_capa = capa; - } - } -} -#else -#define mrb_gc_arena_shrink(mrb,idx) -#endif - -#define CALL_MAXARGS 127 - -void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); - -static inline void -stack_clear(mrb_value *from, size_t count) -{ -#ifndef MRB_NAN_BOXING - const mrb_value mrb_value_zero = { { 0 } }; - - while (count-- > 0) { - *from++ = mrb_value_zero; - } -#else - while (count-- > 0) { - SET_NIL_VALUE(*from); - from++; - } -#endif -} - -static inline void -stack_copy(mrb_value *dst, const mrb_value *src, size_t size) -{ - while (size-- > 0) { - *dst++ = *src++; - } -} - -static void -stack_init(mrb_state *mrb) -{ - struct mrb_context *c = mrb->c; - - /* mrb_assert(mrb->stack == NULL); */ - c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); - c->stend = c->stbase + STACK_INIT_SIZE; - c->stack = c->stbase; - - /* mrb_assert(ci == NULL); */ - c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); - c->ciend = c->cibase + CALLINFO_INIT_SIZE; - c->ci = c->cibase; - c->ci->target_class = mrb->object_class; - c->ci->stackent = c->stack; -} - -static inline void -envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size) -{ - mrb_callinfo *ci = mrb->c->cibase; - - if (newbase == oldbase) return; - while (ci <= mrb->c->ci) { - struct REnv *e = ci->env; - mrb_value *st; - - if (e && MRB_ENV_STACK_SHARED_P(e) && - (st = e->stack) && oldbase <= st && st < oldbase+size) { - ptrdiff_t off = e->stack - oldbase; - - e->stack = newbase + off; - } - ci->stackent = newbase + (ci->stackent - oldbase); - ci++; - } -} - -/** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end */ - -static void -stack_extend_alloc(mrb_state *mrb, int room) -{ - mrb_value *oldbase = mrb->c->stbase; - mrb_value *newstack; - size_t oldsize = mrb->c->stend - mrb->c->stbase; - size_t size = oldsize; - size_t off = mrb->c->stack - mrb->c->stbase; - - if (off > size) size = off; -#ifdef MRB_STACK_EXTEND_DOUBLING - if (room <= size) - size *= 2; - else - size += room; -#else - /* Use linear stack growth. - It is slightly slower than doubling the stack space, - but it saves memory on small devices. */ - if (room <= MRB_STACK_GROWTH) - size += MRB_STACK_GROWTH; - else - size += room; -#endif - - newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); - if (newstack == NULL) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } - stack_clear(&(newstack[oldsize]), size - oldsize); - envadjust(mrb, oldbase, newstack, size); - mrb->c->stbase = newstack; - mrb->c->stack = mrb->c->stbase + off; - mrb->c->stend = mrb->c->stbase + size; - - /* Raise an exception if the new stack size will be too large, - to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */ - if (size > MRB_STACK_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } -} - -static inline void -stack_extend(mrb_state *mrb, int room) -{ - if (mrb->c->stack + room >= mrb->c->stend) { - stack_extend_alloc(mrb, room); - } -} - -static inline struct REnv* -uvenv(mrb_state *mrb, int up) -{ - struct REnv *e = mrb->c->ci->proc->env; - - while (up--) { - if (!e) return NULL; - e = (struct REnv*)e->c; - } - return e; -} - -static inline mrb_bool -is_strict(mrb_state *mrb, struct REnv *e) -{ - ptrdiff_t cioff = e->cioff; - - if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc && - MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) { - return TRUE; - } - return FALSE; -} - -static inline struct REnv* -top_env(mrb_state *mrb, struct RProc *proc) -{ - struct REnv *e = proc->env; - - if (is_strict(mrb, e)) return e; - while (e->c) { - e = (struct REnv*)e->c; - if (is_strict(mrb, e)) return e; - } - return e; -} - -#define CI_ACC_SKIP -1 -#define CI_ACC_DIRECT -2 -#define CI_ACC_RESUMED -3 - -static inline mrb_callinfo* -cipush(mrb_state *mrb) -{ - struct mrb_context *c = mrb->c; - static const mrb_callinfo ci_zero = { 0 }; - mrb_callinfo *ci = c->ci; - - int ridx = ci->ridx; - - if (ci + 1 == c->ciend) { - ptrdiff_t size = ci - c->cibase; - - c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2); - c->ci = c->cibase + size; - c->ciend = c->cibase + size * 2; - } - ci = ++c->ci; - *ci = ci_zero; - ci->epos = mrb->c->eidx; - ci->ridx = ridx; - - return ci; -} - -MRB_API void -mrb_env_unshare(mrb_state *mrb, struct REnv *e) -{ - if (e == NULL) return; - else { - size_t len = (size_t)MRB_ENV_STACK_LEN(e); - ptrdiff_t cioff = e->cioff; - mrb_value *p; - - if (!MRB_ENV_STACK_SHARED_P(e)) return; - if (e->cxt.c != mrb->c) return; - if (e->cioff == 0 && e->cxt.c == mrb->root_c) return; - MRB_ENV_UNSHARE_STACK(e); - if (!e->c) { - /* save block argument position (negated) */ - e->cioff = -e->cxt.c->cibase[cioff].argc-1; - if (e->cioff == 0) e->cioff = -2; /* blkarg position for vararg (1:args, 2:blk) */ - } - e->cxt.mid = e->cxt.c->cibase[cioff].mid; - p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); - if (len > 0) { - stack_copy(p, e->stack, len); - } - e->stack = p; - mrb_write_barrier(mrb, (struct RBasic *)e); - } -} - -static inline void -cipop(mrb_state *mrb) -{ - struct mrb_context *c = mrb->c; - struct REnv *env = c->ci->env; - - c->ci--; - mrb_env_unshare(mrb, env); -} - -void mrb_exc_set(mrb_state *mrb, mrb_value exc); - -static void -ecall(mrb_state *mrb, int i) -{ - struct RProc *p; - mrb_callinfo *ci = mrb->c->ci; - mrb_value *self = mrb->c->stack; - struct RObject *exc; - ptrdiff_t cioff; - int ai = mrb_gc_arena_save(mrb); - - if (i<0) return; - if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } - p = mrb->c->ensure[i]; - if (!p) return; - mrb->c->ensure[i] = NULL; - cioff = ci - mrb->c->cibase; - ci = cipush(mrb); - ci->stackent = mrb->c->stack; - ci->mid = ci[-1].mid; - ci->acc = CI_ACC_SKIP; - ci->argc = 0; - ci->proc = p; - ci->nregs = p->body.irep->nregs; - ci->target_class = p->target_class; - mrb->c->stack = mrb->c->stack + ci[-1].nregs; - exc = mrb->exc; mrb->exc = 0; - if (exc) { - mrb_gc_protect(mrb, mrb_obj_value(exc)); - } - mrb_run(mrb, p, *self); - mrb->c->ci = mrb->c->cibase + cioff; - if (!mrb->exc) mrb->exc = exc; - mrb_gc_arena_restore(mrb, ai); -} - -#ifndef MRB_FUNCALL_ARGC_MAX -#define MRB_FUNCALL_ARGC_MAX 16 -#endif - -MRB_API mrb_value -mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) -{ - mrb_value argv[MRB_FUNCALL_ARGC_MAX]; - va_list ap; - mrb_int i; - mrb_sym mid = mrb_intern_cstr(mrb, name); - - if (argc > MRB_FUNCALL_ARGC_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" MRB_STRINGIZE(MRB_FUNCALL_ARGC_MAX) ")"); - } - - va_start(ap, argc); - for (i = 0; i < argc; i++) { - argv[i] = va_arg(ap, mrb_value); - } - va_end(ap); - return mrb_funcall_argv(mrb, self, mid, argc, argv); -} - -MRB_API mrb_value -mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) -{ - mrb_value val; - - if (!mrb->jmp) { - struct mrb_jmpbuf c_jmp; - ptrdiff_t nth_ci = mrb->c->ci - mrb->c->cibase; - - MRB_TRY(&c_jmp) { - mrb->jmp = &c_jmp; - /* recursive call */ - val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk); - mrb->jmp = 0; - } - MRB_CATCH(&c_jmp) { /* error */ - while (nth_ci < (mrb->c->ci - mrb->c->cibase)) { - mrb->c->stack = mrb->c->ci->stackent; - cipop(mrb); - } - mrb->jmp = 0; - val = mrb_obj_value(mrb->exc); - } - MRB_END_EXC(&c_jmp); - mrb->jmp = 0; - } - else { - struct RProc *p; - struct RClass *c; - mrb_callinfo *ci; - int n; - ptrdiff_t voff = -1; - - if (!mrb->c->stack) { - stack_init(mrb); - } - n = mrb->c->ci->nregs; - if (argc < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc)); - } - c = mrb_class(mrb, self); - p = mrb_method_search_vm(mrb, &c, mid); - if (!p) { - mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); - mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - p = mrb_method_search_vm(mrb, &c, missing); - if (!p) { - mrb_method_missing(mrb, mid, self, args); - } - mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); - stack_extend(mrb, n+2); - mrb->c->stack[n+1] = args; - argc = -1; - } - if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } - ci = cipush(mrb); - ci->mid = mid; - ci->proc = p; - ci->stackent = mrb->c->stack; - ci->argc = argc; - ci->target_class = c; - mrb->c->stack = mrb->c->stack + n; - if (mrb->c->stbase <= argv && argv < mrb->c->stend) { - voff = argv - mrb->c->stbase; - } - if (MRB_PROC_CFUNC_P(p)) { - ci->nregs = argc + 2; - stack_extend(mrb, ci->nregs); - } - else if (argc >= CALL_MAXARGS) { - mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - stack_extend(mrb, ci->nregs); - mrb->c->stack[1] = args; - ci->argc = -1; - argc = 1; - } - else { - if (argc < 0) argc = 1; - ci->nregs = p->body.irep->nregs + argc; - stack_extend(mrb, ci->nregs); - } - if (voff >= 0) { - argv = mrb->c->stbase + voff; - } - mrb->c->stack[0] = self; - if (ci->argc > 0) { - stack_copy(mrb->c->stack+1, argv, argc); - } - mrb->c->stack[argc+1] = blk; - - if (MRB_PROC_CFUNC_P(p)) { - int ai = mrb_gc_arena_save(mrb); - - ci->acc = CI_ACC_DIRECT; - val = p->body.func(mrb, self); - mrb->c->stack = mrb->c->ci->stackent; - cipop(mrb); - mrb_gc_arena_restore(mrb, ai); - } - else { - ci->acc = CI_ACC_SKIP; - val = mrb_run(mrb, p, self); - } - } - mrb_gc_protect(mrb, val); - return val; -} - -MRB_API mrb_value -mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv) -{ - return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value()); -} - -mrb_value -mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) -{ - mrb_callinfo *ci = mrb->c->ci; - - mrb->c->stack[0] = self; - ci->proc = p; - ci->target_class = p->target_class; - if (MRB_PROC_CFUNC_P(p)) { - return p->body.func(mrb, self); - } - ci->nregs = p->body.irep->nregs; - stack_extend(mrb, (ci->argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); - - ci = cipush(mrb); - ci->nregs = 0; - ci->target_class = 0; - ci->pc = p->body.irep->iseq; - ci->stackent = mrb->c->stack; - ci->acc = 0; - - return self; -} - -/* 15.3.1.3.4 */ -/* 15.3.1.3.44 */ -/* - * call-seq: - * obj.send(symbol [, args...]) -> obj - * obj.__send__(symbol [, args...]) -> obj - * - * Invokes the method identified by _symbol_, passing it any - * arguments specified. You can use <code>__send__</code> if the name - * +send+ clashes with an existing method in _obj_. - * - * class Klass - * def hello(*args) - * "Hello " + args.join(' ') - * end - * end - * k = Klass.new - * k.send :hello, "gentle", "readers" #=> "Hello gentle readers" - */ -MRB_API mrb_value -mrb_f_send(mrb_state *mrb, mrb_value self) -{ - mrb_sym name; - mrb_value block, *argv, *regs; - mrb_int argc, i, len; - struct RProc *p; - struct RClass *c; - mrb_callinfo *ci; - - mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block); - ci = mrb->c->ci; - if (ci->acc < 0) { - funcall: - return mrb_funcall_with_block(mrb, self, name, argc, argv, block); - } - - c = mrb_class(mrb, self); - p = mrb_method_search_vm(mrb, &c, name); - - if (!p) { /* call method_mising */ - goto funcall; - } - - ci->mid = name; - ci->target_class = c; - regs = mrb->c->stack+1; - /* remove first symbol from arguments */ - if (ci->argc >= 0) { - for (i=0,len=ci->argc; i<len; i++) { - regs[i] = regs[i+1]; - } - ci->argc--; - } - else { /* variable length arguments */ - mrb_ary_shift(mrb, regs[0]); - } - - return mrb_exec_irep(mrb, self, p); -} - -static mrb_value -eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) -{ - struct RProc *p; - mrb_callinfo *ci; - - if (mrb_nil_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - ci = mrb->c->ci; - if (ci->acc == CI_ACC_DIRECT) { - ci->target_class = c; - return mrb_yield_cont(mrb, blk, self, 1, &self); - } - ci->target_class = c; - p = mrb_proc_ptr(blk); - ci->proc = p; - ci->argc = 1; - ci->mid = ci[-1].mid; - if (MRB_PROC_CFUNC_P(p)) { - stack_extend(mrb, 3); - mrb->c->stack[0] = self; - mrb->c->stack[1] = self; - mrb->c->stack[2] = mrb_nil_value(); - return p->body.func(mrb, self); - } - ci->nregs = p->body.irep->nregs; - stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs); - mrb->c->stack[0] = self; - mrb->c->stack[1] = self; - mrb->c->stack[2] = mrb_nil_value(); - ci = cipush(mrb); - ci->nregs = 0; - ci->target_class = 0; - ci->pc = p->body.irep->iseq; - ci->stackent = mrb->c->stack; - ci->acc = 0; - - return self; -} - -/* 15.2.2.4.35 */ -/* - * call-seq: - * mod.class_eval {| | block } -> obj - * mod.module_eval {| | block } -> obj - * - * Evaluates block in the context of _mod_. This can - * be used to add methods to a class. <code>module_eval</code> returns - * the result of evaluating its argument. - */ -mrb_value -mrb_mod_module_eval(mrb_state *mrb, mrb_value mod) -{ - mrb_value a, b; - - if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { - mrb_raise(mrb, E_NOTIMP_ERROR, "module_eval/class_eval with string not implemented"); - } - return eval_under(mrb, mod, b, mrb_class_ptr(mod)); -} - -/* 15.3.1.3.18 */ -/* - * call-seq: - * obj.instance_eval {| | block } -> obj - * - * Evaluates the given block,within the context of the receiver (_obj_). - * In order to set the context, the variable +self+ is set to _obj_ while - * the code is executing, giving the code access to _obj_'s - * instance variables. In the version of <code>instance_eval</code> - * that takes a +String+, the optional second and third - * parameters supply a filename and starting line number that are used - * when reporting compilation errors. - * - * class KlassWithSecret - * def initialize - * @secret = 99 - * end - * end - * k = KlassWithSecret.new - * k.instance_eval { @secret } #=> 99 - */ -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: - case MRB_TT_FLOAT: - c = 0; - break; - default: - cv = mrb_singleton_class(mrb, self); - c = mrb_class_ptr(cv); - break; - } - return eval_under(mrb, self, b, c); -} - -MRB_API mrb_value -mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c) -{ - struct RProc *p; - mrb_sym mid = mrb->c->ci->mid; - mrb_callinfo *ci; - int n = mrb->c->ci->nregs; - mrb_value val; - - if (mrb_nil_p(b)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } - p = mrb_proc_ptr(b); - ci = cipush(mrb); - ci->mid = mid; - ci->proc = p; - ci->stackent = mrb->c->stack; - ci->argc = argc; - ci->target_class = c; - ci->acc = CI_ACC_SKIP; - mrb->c->stack = mrb->c->stack + n; - ci->nregs = MRB_PROC_CFUNC_P(p) ? argc+2 : p->body.irep->nregs; - stack_extend(mrb, ci->nregs); - - mrb->c->stack[0] = self; - if (argc > 0) { - stack_copy(mrb->c->stack+1, argv, argc); - } - mrb->c->stack[argc+1] = mrb_nil_value(); - - if (MRB_PROC_CFUNC_P(p)) { - val = p->body.func(mrb, self); - mrb->c->stack = mrb->c->ci->stackent; - } - else { - ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase; - val = mrb_run(mrb, p, self); - mrb->c->ci = mrb->c->cibase + cioff; - } - cipop(mrb); - return val; -} - -MRB_API mrb_value -mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv) -{ - struct RProc *p = mrb_proc_ptr(b); - - return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class); -} - -MRB_API mrb_value -mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg) -{ - struct RProc *p = mrb_proc_ptr(b); - - return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class); -} - -mrb_value -mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv) -{ - struct RProc *p; - mrb_callinfo *ci; - - if (mrb_nil_p(b)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - if (mrb_type(b) != MRB_TT_PROC) { - mrb_raise(mrb, E_TYPE_ERROR, "not a block"); - } - - p = mrb_proc_ptr(b); - ci = mrb->c->ci; - - stack_extend(mrb, 3); - mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); - mrb->c->stack[2] = mrb_nil_value(); - ci->argc = -1; - return mrb_exec_irep(mrb, self, p); -} - -mrb_value -mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod) -{ - struct RProc *proc; - mrb_irep *irep; - mrb_value ary; - struct RClass *c; - - mrb_get_args(mrb, ""); - ary = mrb_ary_new(mrb); - proc = mrb->c->ci[-1].proc; /* callee proc */ - c = proc->target_class; - mrb_ary_push(mrb, ary, mrb_obj_value(c)); - mrb_assert(!MRB_PROC_CFUNC_P(proc)); - irep = proc->body.irep; - while (irep) { - if (irep->target_class && irep->target_class != c) { - c = irep->target_class; - mrb_ary_push(mrb, ary, mrb_obj_value(c)); - } - irep = irep->outer; - } - return ary; -} - -static struct RBreak* -break_new(mrb_state *mrb, struct RProc *p, mrb_value val) -{ - struct RBreak *brk; - - brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL); - brk->iv = NULL; - brk->proc = p; - brk->val = val; - - return brk; -} - -typedef enum { - LOCALJUMP_ERROR_RETURN = 0, - LOCALJUMP_ERROR_BREAK = 1, - LOCALJUMP_ERROR_YIELD = 2 -} localjump_error_kind; - -static void -localjump_error(mrb_state *mrb, localjump_error_kind kind) -{ - char kind_str[3][7] = { "return", "break", "yield" }; - char kind_str_len[] = { 6, 5, 5 }; - static const char lead[] = "unexpected "; - mrb_value msg; - mrb_value exc; - - msg = mrb_str_new_capa(mrb, sizeof(lead) + 7); - mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1); - mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]); - exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); - mrb_exc_set(mrb, exc); -} - -static void -argnum_error(mrb_state *mrb, mrb_int num) -{ - mrb_value exc; - mrb_value str; - mrb_int argc = mrb->c->ci->argc; - - if (argc < 0) { - mrb_value args = mrb->c->stack[1]; - if (mrb_array_p(args)) { - argc = RARRAY_LEN(args); - } - } - if (mrb->c->ci->mid) { - str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)", - mrb_sym2str(mrb, mrb->c->ci->mid), - mrb_fixnum_value(argc), mrb_fixnum_value(num)); - } - else { - str = mrb_format(mrb, "wrong number of arguments (%S for %S)", - mrb_fixnum_value(argc), mrb_fixnum_value(num)); - } - exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str); - mrb_exc_set(mrb, exc); -} - -void -irep_uplink(mrb_state *mrb, mrb_irep *outer, mrb_irep *irep) -{ - if (irep->outer != outer) { - if (irep->outer) { - mrb_irep_decref(mrb, irep->outer); - } - irep->outer = outer; - mrb_irep_incref(mrb, outer); - } -} - -#define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc; -#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; -#ifdef MRB_ENABLE_DEBUG_HOOK -#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); -#else -#define CODE_FETCH_HOOK(mrb, irep, pc, regs) -#endif - -#ifdef MRB_BYTECODE_DECODE_OPTION -#define BYTECODE_DECODER(x) ((mrb)->bytecode_decoder)?(mrb)->bytecode_decoder((mrb), (x)):(x) -#else -#define BYTECODE_DECODER(x) (x) -#endif - - -#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER -#define DIRECT_THREADED -#endif - -#ifndef DIRECT_THREADED - -#define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) { -#define CASE(op) case op: -#define NEXT pc++; break -#define JUMP break -#define END_DISPATCH }} - -#else - -#define INIT_DISPATCH JUMP; return mrb_nil_value(); -#define CASE(op) L_ ## op: -#define NEXT i=BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)] -#define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)] - -#define END_DISPATCH - -#endif - -MRB_API mrb_value -mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep) -{ - mrb_irep *irep = proc->body.irep; - mrb_value result; - struct mrb_context *c = mrb->c; - ptrdiff_t cioff = c->ci - c->cibase; - unsigned int nregs = irep->nregs; - - if (!c->stack) { - stack_init(mrb); - } - if (stack_keep > nregs) - nregs = stack_keep; - stack_extend(mrb, nregs); - stack_clear(c->stack + stack_keep, nregs - stack_keep); - c->stack[0] = self; - result = mrb_vm_exec(mrb, proc, irep->iseq); - if (c->ci - c->cibase > cioff) { - c->ci = c->cibase + cioff; - } - if (mrb->c != c) { - if (mrb->c->fib) { - mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib); - } - mrb->c = c; - } - return result; -} - -MRB_API mrb_value -mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) -{ - /* mrb_assert(mrb_proc_cfunc_p(proc)) */ - mrb_irep *irep = proc->body.irep; - mrb_value *pool = irep->pool; - mrb_sym *syms = irep->syms; - mrb_code i; - int ai = mrb_gc_arena_save(mrb); - struct mrb_jmpbuf *prev_jmp = mrb->jmp; - struct mrb_jmpbuf c_jmp; - -#ifdef DIRECT_THREADED - static void *optable[] = { - &&L_OP_NOP, &&L_OP_MOVE, - &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL, - &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF, - &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL, - &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV, - &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST, - &&L_OP_GETUPVAR, &&L_OP_SETUPVAR, - &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT, - &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP, - &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND, - &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER, - &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH, - &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV, - &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE, - &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST, - &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH, - &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS, - &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC, - &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS, - &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR, - }; -#endif - - mrb_bool exc_catched = FALSE; -RETRY_TRY_BLOCK: - - MRB_TRY(&c_jmp) { - - if (exc_catched) { - exc_catched = FALSE; - if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK) - goto L_BREAK; - goto L_RAISE; - } - mrb->jmp = &c_jmp; - mrb->c->ci->proc = proc; - mrb->c->ci->nregs = irep->nregs; - -#define regs (mrb->c->stack) - INIT_DISPATCH { - CASE(OP_NOP) { - /* do nothing */ - NEXT; - } - - CASE(OP_MOVE) { - /* A B R(A) := R(B) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - regs[a] = regs[b]; - NEXT; - } - - CASE(OP_LOADL) { - /* A Bx R(A) := Pool(Bx) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); -#ifdef MRB_WORD_BOXING - mrb_value val = pool[bx]; - if (mrb_float_p(val)) { - val = mrb_float_value(mrb, mrb_float(val)); - } - regs[a] = val; -#else - regs[a] = pool[bx]; -#endif - NEXT; - } - - CASE(OP_LOADI) { - /* A sBx R(A) := sBx */ - SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i)); - NEXT; - } - - CASE(OP_LOADSYM) { - /* A Bx R(A) := Syms(Bx) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - SET_SYM_VALUE(regs[a], syms[bx]); - NEXT; - } - - CASE(OP_LOADSELF) { - /* A R(A) := self */ - int a = GETARG_A(i); - regs[a] = regs[0]; - NEXT; - } - - CASE(OP_LOADT) { - /* A R(A) := true */ - int a = GETARG_A(i); - SET_TRUE_VALUE(regs[a]); - NEXT; - } - - CASE(OP_LOADF) { - /* A R(A) := false */ - int a = GETARG_A(i); - SET_FALSE_VALUE(regs[a]); - NEXT; - } - - CASE(OP_GETGLOBAL) { - /* A Bx R(A) := getglobal(Syms(Bx)) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_value val = mrb_gv_get(mrb, syms[bx]); - regs[a] = val; - NEXT; - } - - CASE(OP_SETGLOBAL) { - /* A Bx setglobal(Syms(Bx), R(A)) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_gv_set(mrb, syms[bx], regs[a]); - NEXT; - } - - CASE(OP_GETSPECIAL) { - /* A Bx R(A) := Special[Bx] */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_value val = mrb_vm_special_get(mrb, bx); - regs[a] = val; - NEXT; - } - - CASE(OP_SETSPECIAL) { - /* A Bx Special[Bx] := R(A) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_vm_special_set(mrb, bx, regs[a]); - NEXT; - } - - CASE(OP_GETIV) { - /* A Bx R(A) := ivget(Bx) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_value val = mrb_vm_iv_get(mrb, syms[bx]); - regs[a] = val; - NEXT; - } - - CASE(OP_SETIV) { - /* A Bx ivset(Syms(Bx),R(A)) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_vm_iv_set(mrb, syms[bx], regs[a]); - NEXT; - } - - CASE(OP_GETCV) { - /* A Bx R(A) := cvget(Syms(Bx)) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_value val; - ERR_PC_SET(mrb, pc); - val = mrb_vm_cv_get(mrb, syms[bx]); - ERR_PC_CLR(mrb); - regs[a] = val; - NEXT; - } - - CASE(OP_SETCV) { - /* A Bx cvset(Syms(Bx),R(A)) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_vm_cv_set(mrb, syms[bx], regs[a]); - NEXT; - } - - CASE(OP_GETCONST) { - /* A Bx R(A) := constget(Syms(Bx)) */ - mrb_value val; - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_sym sym = syms[bx]; - - ERR_PC_SET(mrb, pc); - val = mrb_vm_const_get(mrb, sym); - ERR_PC_CLR(mrb); - regs[a] = val; - NEXT; - } - - CASE(OP_SETCONST) { - /* A Bx constset(Syms(Bx),R(A)) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_vm_const_set(mrb, syms[bx], regs[a]); - NEXT; - } - - CASE(OP_GETMCNST) { - /* A Bx R(A) := R(A)::Syms(Bx) */ - mrb_value val; - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - - ERR_PC_SET(mrb, pc); - val = mrb_const_get(mrb, regs[a], syms[bx]); - ERR_PC_CLR(mrb); - regs[a] = val; - NEXT; - } - - CASE(OP_SETMCNST) { - /* A Bx R(A+1)::Syms(Bx) := R(A) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]); - NEXT; - } - - CASE(OP_GETUPVAR) { - /* A B C R(A) := uvget(B,C) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - mrb_value *regs_a = regs + a; - struct REnv *e = uvenv(mrb, c); - - if (!e) { - *regs_a = mrb_nil_value(); - } - else { - *regs_a = e->stack[b]; - } - NEXT; - } - - CASE(OP_SETUPVAR) { - /* A B C uvset(B,C,R(A)) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - - struct REnv *e = uvenv(mrb, c); - - if (e) { - mrb_value *regs_a = regs + a; - - if (b < MRB_ENV_STACK_LEN(e)) { - e->stack[b] = *regs_a; - mrb_write_barrier(mrb, (struct RBasic*)e); - } - } - NEXT; - } - - CASE(OP_JMP) { - /* sBx pc+=sBx */ - int sbx = GETARG_sBx(i); - pc += sbx; - JUMP; - } - - CASE(OP_JMPIF) { - /* A sBx if R(A) pc+=sBx */ - int a = GETARG_A(i); - int sbx = GETARG_sBx(i); - if (mrb_test(regs[a])) { - pc += sbx; - JUMP; - } - NEXT; - } - - CASE(OP_JMPNOT) { - /* A sBx if !R(A) pc+=sBx */ - int a = GETARG_A(i); - int sbx = GETARG_sBx(i); - if (!mrb_test(regs[a])) { - pc += sbx; - JUMP; - } - NEXT; - } - - CASE(OP_ONERR) { - /* sBx pc+=sBx on exception */ - int sbx = GETARG_sBx(i); - if (mrb->c->rsize <= mrb->c->ci->ridx) { - if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE; - else mrb->c->rsize *= 2; - mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize); - } - mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx; - NEXT; - } - - CASE(OP_RESCUE) { - /* A B R(A) := exc; clear(exc); R(B) := matched (bool) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - mrb_value exc; - - if (c == 0) { - exc = mrb_obj_value(mrb->exc); - mrb->exc = 0; - } - else { /* continued; exc taken from R(A) */ - exc = regs[a]; - } - if (b != 0) { - mrb_value e = regs[b]; - struct RClass *ec; - - switch (mrb_type(e)) { - case MRB_TT_CLASS: - case MRB_TT_MODULE: - break; - default: - { - mrb_value exc; - - exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, - "class or module required for rescue clause"); - mrb_exc_set(mrb, exc); - goto L_RAISE; - } - } - ec = mrb_class_ptr(e); - regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec)); - } - if (a != 0 && c == 0) { - regs[a] = exc; - } - NEXT; - } - - CASE(OP_POPERR) { - /* A A.times{rescue_pop()} */ - int a = GETARG_A(i); - - mrb->c->ci->ridx -= a; - NEXT; - } - - CASE(OP_RAISE) { - /* A raise(R(A)) */ - int a = GETARG_A(i); - - mrb_exc_set(mrb, regs[a]); - goto L_RAISE; - } - - CASE(OP_EPUSH) { - /* Bx ensure_push(SEQ[Bx]) */ - int bx = GETARG_Bx(i); - struct RProc *p; - - p = mrb_closure_new(mrb, irep->reps[bx]); - /* push ensure_stack */ - if (mrb->c->esize <= mrb->c->eidx+1) { - if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE; - else mrb->c->esize *= 2; - mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize); - } - mrb->c->ensure[mrb->c->eidx++] = p; - mrb->c->ensure[mrb->c->eidx] = NULL; - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_EPOP) { - /* A A.times{ensure_pop().call} */ - int a = GETARG_A(i); - mrb_callinfo *ci = mrb->c->ci; - int n, epos = ci->epos; - - for (n=0; n<a && mrb->c->eidx > epos; n++) { - ecall(mrb, --mrb->c->eidx); - mrb_gc_arena_restore(mrb, ai); - } - NEXT; - } - - CASE(OP_LOADNIL) { - /* A R(A) := nil */ - int a = GETARG_A(i); - - SET_NIL_VALUE(regs[a]); - NEXT; - } - - 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),Syms(B),R(A+1),...,R(A+C)) */ - int a = GETARG_A(i); - int n = GETARG_C(i); - int argc = (n == CALL_MAXARGS) ? -1 : n; - int bidx = (argc < 0) ? a+2 : a+n+1; - struct RProc *m; - struct RClass *c; - mrb_callinfo *ci = mrb->c->ci; - mrb_value recv, blk; - mrb_sym mid = syms[GETARG_B(i)]; - - mrb_assert(bidx < ci->nregs); - - recv = regs[a]; - if (GET_OPCODE(i) != OP_SENDB) { - SET_NIL_VALUE(regs[bidx]); - blk = regs[bidx]; - } - else { - blk = regs[bidx]; - if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { - blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); - /* The stack might have been reallocated during mrb_convert_type(), - see #3622 */ - regs[bidx] = blk; - } - } - c = mrb_class(mrb, recv); - m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { - mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); - m = mrb_method_search_vm(mrb, &c, missing); - if (!m) { - mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, n, regs+a+1); - ERR_PC_SET(mrb, pc); - mrb_method_missing(mrb, mid, recv, args); - } - if (argc >= 0) { - if (a+2 >= irep->nregs) { - stack_extend(mrb, a+3); - } - regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); - regs[a+2] = blk; - argc = -1; - } - mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid)); - mid = missing; - } - - /* push callinfo */ - ci = cipush(mrb); - ci->mid = mid; - ci->proc = m; - ci->stackent = mrb->c->stack; - ci->target_class = c; - ci->argc = argc; - - ci->pc = pc + 1; - ci->acc = a; - - /* prepare stack */ - mrb->c->stack += a; - - if (MRB_PROC_CFUNC_P(m)) { - ci->nregs = (argc < 0) ? 3 : n+2; - recv = m->body.func(mrb, recv); - mrb_gc_arena_restore(mrb, ai); - mrb_gc_arena_shrink(mrb, ai); - if (mrb->exc) goto L_RAISE; - ci = mrb->c->ci; - if (GET_OPCODE(i) == OP_SENDB) { - if (mrb_type(blk) == MRB_TT_PROC) { - struct RProc *p = mrb_proc_ptr(blk); - if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) { - p->flags |= MRB_PROC_ORPHAN; - } - } - } - if (!ci->target_class) { /* return from context modifying method (resume/yield) */ - if (ci->acc == CI_ACC_RESUMED) { - mrb->jmp = prev_jmp; - return recv; - } - else { - mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc)); - proc = ci[-1].proc; - irep = proc->body.irep; - pool = irep->pool; - syms = irep->syms; - } - } - mrb->c->stack[0] = recv; - /* pop stackpos */ - mrb->c->stack = ci->stackent; - pc = ci->pc; - cipop(mrb); - JUMP; - } - else { - /* setup environment for calling method */ - proc = mrb->c->ci->proc = m; - irep = m->body.irep; - pool = irep->pool; - syms = irep->syms; - ci->nregs = irep->nregs; - stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); - pc = irep->iseq; - JUMP; - } - } - - CASE(OP_FSEND) { - /* A B C R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */ - /* not implemented yet */ - NEXT; - } - - CASE(OP_CALL) { - /* A R(A) := self.call(frame.argc, frame.argv) */ - mrb_callinfo *ci; - mrb_value recv = mrb->c->stack[0]; - struct RProc *m = mrb_proc_ptr(recv); - - /* replace callinfo */ - ci = mrb->c->ci; - ci->target_class = m->target_class; - ci->proc = m; - if (m->env) { - mrb_sym mid; - - if (MRB_ENV_STACK_SHARED_P(m->env)) { - mid = m->env->cxt.c->cibase[m->env->cioff].mid; - } - else { - mid = m->env->cxt.mid; - } - if (mid) ci->mid = mid; - if (!m->env->stack) { - m->env->stack = mrb->c->stack; - } - } - - /* prepare stack */ - if (MRB_PROC_CFUNC_P(m)) { - recv = m->body.func(mrb, recv); - mrb_gc_arena_restore(mrb, ai); - mrb_gc_arena_shrink(mrb, ai); - if (mrb->exc) goto L_RAISE; - /* pop stackpos */ - ci = mrb->c->ci; - mrb->c->stack = ci->stackent; - regs[ci->acc] = recv; - pc = ci->pc; - cipop(mrb); - irep = mrb->c->ci->proc->body.irep; - pool = irep->pool; - syms = irep->syms; - JUMP; - } - else { - /* setup environment for calling method */ - proc = m; - irep = m->body.irep; - if (!irep) { - mrb->c->stack[0] = mrb_nil_value(); - goto L_RETURN; - } - pool = irep->pool; - syms = irep->syms; - ci->nregs = irep->nregs; - stack_extend(mrb, ci->nregs); - if (ci->argc < 0) { - if (irep->nregs > 3) { - stack_clear(regs+3, irep->nregs-3); - } - } - else if (ci->argc+2 < irep->nregs) { - stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2); - } - if (m->env) { - regs[0] = m->env->stack[0]; - } - pc = irep->iseq; - JUMP; - } - } - - CASE(OP_SUPER) { - /* A C R(A) := super(R(A+1),... ,R(A+C+1)) */ - int a = GETARG_A(i); - int n = GETARG_C(i); - int argc = (n == CALL_MAXARGS) ? -1 : n; - int bidx = (argc < 0) ? a+2 : a+n+1; - struct RProc *m; - struct RClass *c; - mrb_callinfo *ci = mrb->c->ci; - mrb_value recv, blk; - mrb_sym mid = ci->mid; - - mrb_assert(bidx < ci->nregs); - - if (mid == 0 || !ci->target_class) { - mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); - mrb_exc_set(mrb, exc); - goto L_RAISE; - } - recv = regs[0]; - blk = regs[bidx]; - if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { - blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); - /* The stack or ci stack might have been reallocated during - mrb_convert_type(), see #3622 and #3784 */ - regs[bidx] = blk; - ci = mrb->c->ci; - } - c = ci->target_class->super; - m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { - mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); - m = mrb_method_search_vm(mrb, &c, missing); - if (!m) { - mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, n, regs+a+1); - ERR_PC_SET(mrb, pc); - mrb_method_missing(mrb, mid, recv, args); - } - mid = missing; - if (argc >= 0) { - if (a+2 >= ci->nregs) { - stack_extend(mrb, a+3); - } - regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); - regs[a+2] = blk; - argc = -1; - } - mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); - } - - /* push callinfo */ - ci = cipush(mrb); - ci->mid = mid; - ci->proc = m; - ci->stackent = mrb->c->stack; - ci->target_class = c; - ci->pc = pc + 1; - ci->argc = argc; - - /* prepare stack */ - mrb->c->stack += a; - mrb->c->stack[0] = recv; - - if (MRB_PROC_CFUNC_P(m)) { - mrb_value v; - ci->nregs = (argc < 0) ? 3 : n+2; - v = m->body.func(mrb, recv); - mrb_gc_arena_restore(mrb, ai); - if (mrb->exc) goto L_RAISE; - ci = mrb->c->ci; - if (!ci->target_class) { /* return from context modifying method (resume/yield) */ - if (ci->acc == CI_ACC_RESUMED) { - mrb->jmp = prev_jmp; - return v; - } - else { - mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc)); - proc = ci[-1].proc; - irep = proc->body.irep; - pool = irep->pool; - syms = irep->syms; - } - } - mrb->c->stack[0] = v; - /* pop stackpos */ - mrb->c->stack = ci->stackent; - pc = ci->pc; - cipop(mrb); - JUMP; - } - else { - /* fill callinfo */ - ci->acc = a; - - /* setup environment for calling method */ - ci->proc = m; - irep = m->body.irep; - pool = irep->pool; - syms = irep->syms; - ci->nregs = irep->nregs; - stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); - pc = irep->iseq; - JUMP; - } - } - - CASE(OP_ARGARY) { - /* A Bx R(A) := argument array (16=6:1:5:4) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - int m1 = (bx>>10)&0x3f; - int r = (bx>>9)&0x1; - int m2 = (bx>>4)&0x1f; - int lv = (bx>>0)&0xf; - mrb_value *stack; - - if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) { - mrb_value exc; - - L_NOSUPER: - exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); - mrb_exc_set(mrb, exc); - goto L_RAISE; - } - if (lv == 0) stack = regs + 1; - else { - struct REnv *e = uvenv(mrb, lv-1); - if (!e) goto L_NOSUPER; - if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) - goto L_NOSUPER; - stack = e->stack + 1; - } - if (r == 0) { - regs[a] = mrb_ary_new_from_values(mrb, m1+m2, stack); - } - else { - mrb_value *pp = NULL; - struct RArray *rest; - int len = 0; - - if (mrb_array_p(stack[m1])) { - struct RArray *ary = mrb_ary_ptr(stack[m1]); - - pp = ARY_PTR(ary); - len = ARY_LEN(ary); - } - regs[a] = mrb_ary_new_capa(mrb, m1+len+m2); - rest = mrb_ary_ptr(regs[a]); - if (m1 > 0) { - stack_copy(ARY_PTR(rest), stack, m1); - } - if (len > 0) { - stack_copy(ARY_PTR(rest)+m1, pp, len); - } - if (m2 > 0) { - stack_copy(ARY_PTR(rest)+m1+len, stack+m1+1, m2); - } - ARY_SET_LEN(rest, m1+len+m2); - } - regs[a+1] = stack[m1+r+m2]; - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_ENTER) { - /* 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 = MRB_ASPEC_REQ(ax); - int o = MRB_ASPEC_OPT(ax); - int r = MRB_ASPEC_REST(ax); - int m2 = MRB_ASPEC_POST(ax); - /* unused - int k = MRB_ASPEC_KEY(ax); - int kd = MRB_ASPEC_KDICT(ax); - int b = MRB_ASPEC_BLOCK(ax); - */ - int argc = mrb->c->ci->argc; - mrb_value *argv = regs+1; - mrb_value *argv0 = argv; - int len = m1 + o + r + m2; - mrb_value *blk = &argv[argc < 0 ? 1 : argc]; - - if (argc < 0) { - struct RArray *ary = mrb_ary_ptr(regs[1]); - argv = ARY_PTR(ary); - argc = ARY_LEN(ary); - mrb_gc_protect(mrb, regs[1]); - } - if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) { - if (argc >= 0) { - if (argc < m1 + m2 || (r == 0 && argc > len)) { - argnum_error(mrb, m1+m2); - goto L_RAISE; - } - } - } - else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) { - mrb_gc_protect(mrb, argv[0]); - argc = RARRAY_LEN(argv[0]); - argv = RARRAY_PTR(argv[0]); - } - 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(®s[1], argv, argc-mlen); /* m1 + o */ - } - if (argc < m1) { - stack_clear(®s[argc+1], m1-argc); - } - if (mlen) { - value_move(®s[len-m2+1], &argv[argc-mlen], mlen); - } - if (mlen < m2) { - stack_clear(®s[len-m2+mlen+1], m2-mlen); - } - if (r) { - regs[m1+o+1] = mrb_ary_new_capa(mrb, 0); - } - if (o == 0 || argc < m1+m2) pc++; - else - pc += argc - m1 - m2 + 1; - } - else { - int rnum = 0; - if (argv0 != argv) { - regs[len+1] = *blk; /* move block */ - value_move(®s[1], argv, m1+o); - } - if (r) { - rnum = argc-m1-o-m2; - regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); - } - if (m2) { - if (argc-m2 > m1) { - value_move(®s[m1+o+r+1], &argv[m1+o+rnum], m2); - } - } - if (argv0 == argv) { - regs[len+1] = *blk; /* move block */ - } - pc += o + 1; - } - mrb->c->ci->argc = len; - /* clear local (but non-argument) variables */ - if (irep->nlocals-len-2 > 0) { - stack_clear(®s[len+2], irep->nlocals-len-2); - } - JUMP; - } - - CASE(OP_KARG) { - /* 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; - } - - CASE(OP_KDICT) { - /* A C R(A) := kdict */ - NEXT; - } - - L_RETURN: - i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL); - /* fall through */ - CASE(OP_RETURN) { - /* A B return R(A) (B=normal,in-block return/break) */ - mrb_callinfo *ci; - - ci = mrb->c->ci; - if (ci->mid) { - mrb_value blk; - - if (ci->argc < 0) { - blk = regs[2]; - } - else { - blk = regs[ci->argc+1]; - } - if (mrb_type(blk) == MRB_TT_PROC) { - struct RProc *p = mrb_proc_ptr(blk); - - if (!MRB_PROC_STRICT_P(p) && - ci > mrb->c->cibase && p->env == ci[-1].env) { - p->flags |= MRB_PROC_ORPHAN; - } - } - } - - if (mrb->exc) { - mrb_callinfo *ci0; - mrb_value *stk; - - L_RAISE: - ci0 = ci = mrb->c->ci; - if (ci == mrb->c->cibase) { - if (ci->ridx == 0) goto L_FTOP; - goto L_RESCUE; - } - stk = mrb->c->stack; - while (ci[0].ridx == ci[-1].ridx) { - cipop(mrb); - mrb->c->stack = ci->stackent; - if (ci->acc == CI_ACC_SKIP && prev_jmp) { - mrb->jmp = prev_jmp; - MRB_THROW(prev_jmp); - } - ci = mrb->c->ci; - if (ci == mrb->c->cibase) { - mrb->c->stack = stk; - if (ci->ridx == 0) { - L_FTOP: /* fiber top */ - if (mrb->c == mrb->root_c) { - mrb->c->stack = mrb->c->stbase; - goto L_STOP; - } - else { - struct mrb_context *c = mrb->c; - - if (c->fib) { - mrb_write_barrier(mrb, (struct RBasic*)c->fib); - } - mrb->c = c->prev; - c->prev = NULL; - goto L_RAISE; - } - } - break; - } - /* call ensure only when we skip this callinfo */ - if (ci[0].ridx == ci[-1].ridx) { - mrb_value *org_stbase = mrb->c->stbase; - while (mrb->c->eidx > ci->epos) { - ecall(mrb, --mrb->c->eidx); - ci = mrb->c->ci; - if (org_stbase != mrb->c->stbase) { - stk = mrb->c->stack; - } - } - } - } - L_RESCUE: - if (ci->ridx == 0) goto L_STOP; - proc = ci->proc; - irep = proc->body.irep; - pool = irep->pool; - syms = irep->syms; - if (ci != ci0) { - mrb->c->stack = ci[1].stackent; - } - stack_extend(mrb, irep->nregs); - pc = mrb->c->rescue[--ci->ridx]; - } - else { - int acc; - mrb_value v; - - v = regs[GETARG_A(i)]; - mrb_gc_protect(mrb, v); - switch (GETARG_B(i)) { - case OP_R_RETURN: - /* Fall through to OP_R_NORMAL otherwise */ - if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) { - struct REnv *e = top_env(mrb, proc); - mrb_callinfo *ce; - - if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) { - localjump_error(mrb, LOCALJUMP_ERROR_RETURN); - goto L_RAISE; - } - - ce = mrb->c->cibase + e->cioff; - while (ci > ce) { - mrb_env_unshare(mrb, ci->env); - if (ci->acc < 0) { - localjump_error(mrb, LOCALJUMP_ERROR_RETURN); - goto L_RAISE; - } - ci--; - } - mrb_env_unshare(mrb, ci->env); - if (ce == mrb->c->cibase) { - localjump_error(mrb, LOCALJUMP_ERROR_RETURN); - goto L_RAISE; - } - mrb->c->stack = mrb->c->ci->stackent; - mrb->c->ci = ce; - break; - } - case OP_R_NORMAL: - NORMAL_RETURN: - if (ci == mrb->c->cibase) { - if (!mrb->c->prev) { /* toplevel return */ - localjump_error(mrb, LOCALJUMP_ERROR_RETURN); - goto L_RAISE; - } - if (mrb->c->prev->ci == mrb->c->prev->cibase) { - mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume"); - mrb_exc_set(mrb, exc); - goto L_RAISE; - } - while (mrb->c->eidx > 0) { - ecall(mrb, --mrb->c->eidx); - } - /* automatic yield at the end */ - mrb->c->status = MRB_FIBER_TERMINATED; - mrb->c = mrb->c->prev; - mrb->c->status = MRB_FIBER_RUNNING; - } - ci = mrb->c->ci; - break; - case OP_R_BREAK: - if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; - if (MRB_PROC_ORPHAN_P(proc)) { - mrb_value exc; - - L_BREAK_ERROR: - exc = mrb_exc_new_str_lit(mrb, E_LOCALJUMP_ERROR, - "break from proc-closure"); - mrb_exc_set(mrb, exc); - goto L_RAISE; - } - if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) { - goto L_BREAK_ERROR; - } - if (proc->env->cxt.c != mrb->c) { - goto L_BREAK_ERROR; - } - while (mrb->c->eidx > mrb->c->ci->epos) { - ecall(mrb, --mrb->c->eidx); - } - /* break from fiber block */ - if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) { - struct mrb_context *c = mrb->c; - - mrb->c = c->prev; - c->prev = NULL; - } - ci = mrb->c->ci; - if (ci->acc < 0) { - mrb_gc_arena_restore(mrb, ai); - mrb->c->vmexec = FALSE; - mrb->exc = (struct RObject*)break_new(mrb, proc, v); - mrb->jmp = prev_jmp; - MRB_THROW(prev_jmp); - } - if (FALSE) { - L_BREAK: - v = ((struct RBreak*)mrb->exc)->val; - proc = ((struct RBreak*)mrb->exc)->proc; - mrb->exc = NULL; - ci = mrb->c->ci; - } - mrb->c->stack = ci->stackent; - mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1; - while (ci > mrb->c->ci) { - mrb_env_unshare(mrb, ci->env); - if (ci[-1].acc == CI_ACC_SKIP) { - mrb->c->ci = ci; - goto L_BREAK_ERROR; - } - ci--; - } - mrb_env_unshare(mrb, ci->env); - break; - default: - /* cannot happen */ - break; - } - while (mrb->c->eidx > mrb->c->ci->epos) { - ecall(mrb, --mrb->c->eidx); - } - if (mrb->c->vmexec && !mrb->c->ci->target_class) { - mrb_gc_arena_restore(mrb, ai); - mrb->c->vmexec = FALSE; - mrb->jmp = prev_jmp; - return v; - } - ci = mrb->c->ci; - acc = ci->acc; - mrb->c->stack = ci->stackent; - cipop(mrb); - if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) { - mrb_gc_arena_restore(mrb, ai); - mrb->jmp = prev_jmp; - return v; - } - pc = ci->pc; - DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid))); - proc = mrb->c->ci->proc; - irep = proc->body.irep; - pool = irep->pool; - syms = irep->syms; - - regs[acc] = v; - mrb_gc_arena_restore(mrb, ai); - } - JUMP; - } - - CASE(OP_TAILCALL) { - /* 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; - struct RClass *c; - mrb_callinfo *ci; - mrb_value recv; - mrb_sym mid = syms[GETARG_B(i)]; - - recv = regs[a]; - c = mrb_class(mrb, recv); - m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { - mrb_value sym = mrb_symbol_value(mid); - mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); - m = mrb_method_search_vm(mrb, &c, missing); - if (!m) { - mrb_value args; - - if (n == CALL_MAXARGS) { - args = regs[a+1]; - } - else { - args = mrb_ary_new_from_values(mrb, n, regs+a+1); - } - ERR_PC_SET(mrb, pc); - mrb_method_missing(mrb, mid, recv, args); - } - mid = missing; - if (n == CALL_MAXARGS) { - mrb_ary_unshift(mrb, regs[a+1], sym); - } - else { - value_move(regs+a+2, regs+a+1, ++n); - regs[a+1] = sym; - } - } - - /* replace callinfo */ - ci = mrb->c->ci; - ci->mid = mid; - ci->target_class = c; - if (n == CALL_MAXARGS) { - ci->argc = -1; - } - else { - ci->argc = n; - } - - /* move stack */ - value_move(mrb->c->stack, ®s[a], ci->argc+1); - - if (MRB_PROC_CFUNC_P(m)) { - mrb_value v = m->body.func(mrb, recv); - mrb->c->stack[0] = v; - mrb_gc_arena_restore(mrb, ai); - goto L_RETURN; - } - else { - /* setup environment for calling method */ - irep = m->body.irep; - pool = irep->pool; - syms = irep->syms; - if (ci->argc < 0) { - stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); - } - else { - stack_extend(mrb, irep->nregs); - } - pc = irep->iseq; - } - JUMP; - } - - CASE(OP_BLKPUSH) { - /* A Bx R(A) := block (16=6:1:5:4) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - int m1 = (bx>>10)&0x3f; - int r = (bx>>9)&0x1; - int m2 = (bx>>4)&0x1f; - int lv = (bx>>0)&0xf; - mrb_value *stack; - - if (lv == 0) stack = regs + 1; - else { - struct REnv *e = uvenv(mrb, lv-1); - if (!e || e->cioff == 0 || - (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0) || - MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) { - localjump_error(mrb, LOCALJUMP_ERROR_YIELD); - goto L_RAISE; - } - stack = e->stack + 1; - } - if (mrb_nil_p(stack[m1+r+m2])) { - localjump_error(mrb, LOCALJUMP_ERROR_YIELD); - goto L_RAISE; - } - regs[a] = stack[m1+r+m2]; - NEXT; - } - -#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) -#define OP_MATH_BODY(op,v1,v2) do {\ - v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ -} while(0) - - CASE(OP_ADD) { - /* A B C R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/ - int a = GETARG_A(i); - - /* need to check if op is overridden */ - 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 *regs_a = regs + a; - - x = mrb_fixnum(regs_a[0]); - y = mrb_fixnum(regs_a[1]); - if (mrb_int_add_overflow(x, y, &z)) { - SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); - break; - } - SET_INT_VALUE(regs[a], z); - } - break; - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y); - } - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x + y); - } -#else - OP_MATH_BODY(+,mrb_float,mrb_fixnum); -#endif - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x + y); - } -#else - OP_MATH_BODY(+,mrb_float,mrb_float); -#endif - break; - case TYPES2(MRB_TT_STRING,MRB_TT_STRING): - regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); - break; - default: - goto L_SEND; - } - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_SUB) { - /* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/ - int a = GETARG_A(i); - - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - - x = mrb_fixnum(regs[a]); - y = mrb_fixnum(regs[a+1]); - if (mrb_int_sub_overflow(x, y, &z)) { - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); - break; - } - SET_INT_VALUE(regs[a], z); - } - break; - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y); - } - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x - y); - } -#else - OP_MATH_BODY(-,mrb_float,mrb_fixnum); -#endif - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x - y); - } -#else - OP_MATH_BODY(-,mrb_float,mrb_float); -#endif - break; - default: - goto L_SEND; - } - NEXT; - } - - CASE(OP_MUL) { - /* A B C R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/ - int a = GETARG_A(i); - - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - - x = mrb_fixnum(regs[a]); - y = mrb_fixnum(regs[a+1]); - if (mrb_int_mul_overflow(x, y, &z)) { - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); - break; - } - SET_INT_VALUE(regs[a], z); - } - break; - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y); - } - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x * y); - } -#else - OP_MATH_BODY(*,mrb_float,mrb_fixnum); -#endif - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x * y); - } -#else - OP_MATH_BODY(*,mrb_float,mrb_float); -#endif - break; - default: - goto L_SEND; - } - NEXT; - } - - CASE(OP_DIV) { - /* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/ - int a = GETARG_A(i); - - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - double f; - if (y == 0) { - if (x > 0) f = INFINITY; - else if (x < 0) f = -INFINITY; - else /* if (x == 0) */ f = NAN; - } - else { - f = (mrb_float)x / (mrb_float)y; - } - SET_FLOAT_VALUE(mrb, regs[a], f); - } - break; - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y); - } - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - double f; - if (y == 0) { - f = INFINITY; - } - else { - f = x / y; - } - SET_FLOAT_VALUE(mrb, regs[a], f); - } -#else - OP_MATH_BODY(/,mrb_float,mrb_fixnum); -#endif - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x / y); - } -#else - OP_MATH_BODY(/,mrb_float,mrb_float); -#endif - break; - default: - goto L_SEND; - } -#ifdef MRB_NAN_BOXING - if (isnan(mrb_float(regs[a]))) { - mrb_value v = mrb_float_value(mrb, mrb_float(regs[a])); - regs[a] = v; - } -#endif - NEXT; - } - - CASE(OP_ADDI) { - /* A B C R(A) := R(A)+C (Syms[B]=:+)*/ - int a = GETARG_A(i); - - /* need to check if + is overridden */ - switch (mrb_type(regs[a])) { - case MRB_TT_FIXNUM: - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_int y = GETARG_C(i); - mrb_int z; - - if (mrb_int_add_overflow(x, y, &z)) { - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); - break; - } - SET_INT_VALUE(regs[a], z); - } - break; - case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - SET_FLOAT_VALUE(mrb, regs[a], x + GETARG_C(i)); - } -#else - mrb_float(regs[a]) += GETARG_C(i); -#endif - break; - default: - SET_INT_VALUE(regs[a+1], GETARG_C(i)); - i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); - goto L_SEND; - } - NEXT; - } - - CASE(OP_SUBI) { - /* A B C R(A) := R(A)-C (Syms[B]=:-)*/ - int a = GETARG_A(i); - mrb_value *regs_a = regs + a; - - /* need to check if + is overridden */ - switch (mrb_type(regs_a[0])) { - case MRB_TT_FIXNUM: - { - mrb_int x = mrb_fixnum(regs_a[0]); - mrb_int y = GETARG_C(i); - mrb_int z; - - if (mrb_int_sub_overflow(x, y, &z)) { - SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y); - } - else { - SET_INT_VALUE(regs_a[0], z); - } - } - break; - case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i)); - } -#else - mrb_float(regs_a[0]) -= GETARG_C(i); -#endif - break; - default: - SET_INT_VALUE(regs_a[1], GETARG_C(i)); - i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); - goto L_SEND; - } - NEXT; - } - -#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) - -#define OP_CMP(op) do {\ - int result;\ - /* need to check if - is overridden */\ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\ - result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\ - break;\ - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):\ - result = OP_CMP_BODY(op,mrb_fixnum,mrb_float);\ - break;\ - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):\ - result = OP_CMP_BODY(op,mrb_float,mrb_fixnum);\ - break;\ - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\ - result = OP_CMP_BODY(op,mrb_float,mrb_float);\ - break;\ - default:\ - goto L_SEND;\ - }\ - if (result) {\ - SET_TRUE_VALUE(regs[a]);\ - }\ - else {\ - SET_FALSE_VALUE(regs[a]);\ - }\ -} while(0) - - CASE(OP_EQ) { - /* 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]); - } - else { - OP_CMP(==); - } - NEXT; - } - - CASE(OP_LT) { - /* A B C R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1)*/ - int a = GETARG_A(i); - OP_CMP(<); - NEXT; - } - - CASE(OP_LE) { - /* A B C R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)*/ - int a = GETARG_A(i); - OP_CMP(<=); - NEXT; - } - - CASE(OP_GT) { - /* 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)*/ - int a = GETARG_A(i); - OP_CMP(>=); - NEXT; - } - - CASE(OP_ARRAY) { - /* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - mrb_value v = mrb_ary_new_from_values(mrb, c, ®s[b]); - regs[a] = v; - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_ARYCAT) { - /* A B mrb_ary_concat(R(A),R(B)) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - mrb_value splat = mrb_ary_splat(mrb, regs[b]); - mrb_ary_concat(mrb, regs[a], splat); - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_ARYPUSH) { - /* A B R(A).push(R(B)) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - mrb_ary_push(mrb, regs[a], regs[b]); - NEXT; - } - - CASE(OP_AREF) { - /* A B C R(A) := R(B)[C] */ - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - mrb_value v = regs[b]; - - if (!mrb_array_p(v)) { - if (c == 0) { - regs[a] = v; - } - else { - SET_NIL_VALUE(regs[a]); - } - } - else { - v = mrb_ary_ref(mrb, v, c); - regs[a] = v; - } - NEXT; - } - - CASE(OP_ASET) { - /* A B C R(B)[C] := R(A) */ - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - mrb_ary_set(mrb, regs[b], c, regs[a]); - NEXT; - } - - CASE(OP_APOST) { - /* A B C *R(A),R(A+1)..R(A+C) := R(A) */ - int a = GETARG_A(i); - mrb_value v = regs[a]; - int pre = GETARG_B(i); - int post = GETARG_C(i); - struct RArray *ary; - int len, idx; - - if (!mrb_array_p(v)) { - v = mrb_ary_new_from_values(mrb, 1, ®s[a]); - } - ary = mrb_ary_ptr(v); - len = ARY_LEN(ary); - if (len > pre + post) { - v = mrb_ary_new_from_values(mrb, len - pre - post, ARY_PTR(ary)+pre); - regs[a++] = v; - while (post--) { - regs[a++] = ARY_PTR(ary)[len-post-1]; - } - } - else { - v = mrb_ary_new_capa(mrb, 0); - regs[a++] = v; - for (idx=0; idx+pre<len; idx++) { - regs[a+idx] = ARY_PTR(ary)[pre+idx]; - } - while (idx < post) { - SET_NIL_VALUE(regs[a+idx]); - idx++; - } - } - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_STRING) { - /* A Bx R(A) := str_new(Lit(Bx)) */ - mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]); - regs[GETARG_A(i)] = str; - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_STRCAT) { - /* A B R(A).concat(R(B)) */ - mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]); - NEXT; - } - - CASE(OP_HASH) { - /* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */ - int b = GETARG_B(i); - int c = GETARG_C(i); - int lim = b+c*2; - mrb_value hash = mrb_hash_new_capa(mrb, c); - - while (b < lim) { - mrb_hash_set(mrb, hash, regs[b], regs[b+1]); - b+=2; - } - regs[GETARG_A(i)] = hash; - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_LAMBDA) { - /* A b c R(A) := lambda(SEQ[b],c) (b:c = 14:2) */ - struct RProc *p; - int a = GETARG_A(i); - int b = GETARG_b(i); - int c = GETARG_c(i); - mrb_irep *nirep = irep->reps[b]; - - irep_uplink(mrb, irep, nirep); - if (c & OP_L_CAPTURE) { - p = mrb_closure_new(mrb, nirep); - } - else { - p = mrb_proc_new(mrb, nirep); - } - if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT; - regs[a] = mrb_obj_value(p); - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_OCLASS) { - /* A R(A) := ::Object */ - regs[GETARG_A(i)] = mrb_obj_value(mrb->object_class); - NEXT; - } - - CASE(OP_CLASS) { - /* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */ - struct RClass *c = 0, *baseclass; - int a = GETARG_A(i); - mrb_value base, super; - mrb_sym id = syms[GETARG_B(i)]; - - base = regs[a]; - super = regs[a+1]; - if (mrb_nil_p(base)) { - baseclass = mrb->c->ci->proc->target_class; - if (!baseclass) baseclass = mrb->c->ci->target_class; - - base = mrb_obj_value(baseclass); - } - c = mrb_vm_define_class(mrb, base, super, id); - regs[a] = mrb_obj_value(c); - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_MODULE) { - /* A B R(A) := newmodule(R(A),Syms(B)) */ - struct RClass *c = 0, *baseclass; - int a = GETARG_A(i); - mrb_value base; - mrb_sym id = syms[GETARG_B(i)]; - - base = regs[a]; - if (mrb_nil_p(base)) { - baseclass = mrb->c->ci->proc->target_class; - if (!baseclass) baseclass = mrb->c->ci->target_class; - - base = mrb_obj_value(baseclass); - } - c = mrb_vm_define_module(mrb, base, id); - regs[a] = mrb_obj_value(c); - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_EXEC) { - /* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */ - int a = GETARG_A(i); - int bx = GETARG_Bx(i); - mrb_callinfo *ci; - mrb_value recv = regs[a]; - struct RProc *p; - mrb_irep *nirep = irep->reps[bx]; - - irep_uplink(mrb, irep, nirep); - nirep->target_class = mrb_class_ptr(recv); - /* prepare closure */ - p = mrb_closure_new(mrb, nirep); - p->c = NULL; - - /* prepare stack */ - ci = cipush(mrb); - ci->pc = pc + 1; - ci->acc = a; - ci->mid = 0; - ci->stackent = mrb->c->stack; - ci->argc = 0; - ci->target_class = mrb_class_ptr(recv); - - /* prepare stack */ - mrb->c->stack += a; - - /* setup closure */ - p->target_class = ci->target_class; - ci->proc = p; - - irep = p->body.irep; - pool = irep->pool; - syms = irep->syms; - ci->nregs = irep->nregs; - stack_extend(mrb, ci->nregs); - stack_clear(regs+1, ci->nregs-1); - pc = irep->iseq; - JUMP; - } - - CASE(OP_METHOD) { - /* A B R(A).newmethod(Syms(B),R(A+1)) */ - int a = GETARG_A(i); - struct RClass *c = mrb_class_ptr(regs[a]); - struct RProc *p = mrb_proc_ptr(regs[a+1]); - - mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p); - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_SCLASS) { - /* A B R(A) := R(B).singleton_class */ - regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]); - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_TCLASS) { - /* 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_set(mrb, exc); - goto L_RAISE; - } - regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class); - NEXT; - } - - CASE(OP_RANGE) { - /* A B C R(A) := range_new(R(B),R(B+1),C) */ - int b = GETARG_B(i); - mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i)); - regs[GETARG_A(i)] = val; - mrb_gc_arena_restore(mrb, ai); - NEXT; - } - - CASE(OP_DEBUG) { - /* A B C debug print R(A),R(B),R(C) */ -#ifdef MRB_ENABLE_DEBUG_HOOK - mrb->debug_op_hook(mrb, irep, pc, regs); -#else -#ifndef MRB_DISABLE_STDIO - printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i)); -#else - abort(); -#endif -#endif - NEXT; - } - - CASE(OP_STOP) { - /* stop VM */ - L_STOP: - { - int epos = mrb->c->ci->epos; - - while (mrb->c->eidx > epos) { - ecall(mrb, --mrb->c->eidx); - } - } - ERR_PC_CLR(mrb); - mrb->jmp = prev_jmp; - if (mrb->exc) { - return mrb_obj_value(mrb->exc); - } - return regs[irep->nlocals]; - } - - CASE(OP_ERR) { - /* Bx raise RuntimeError with message Lit(Bx) */ - mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]); - mrb_value exc; - - if (GETARG_A(i) == 0) { - exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg); - } - else { - exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); - } - ERR_PC_SET(mrb, pc); - mrb_exc_set(mrb, exc); - goto L_RAISE; - } - } - END_DISPATCH; -#undef regs - - } - MRB_CATCH(&c_jmp) { - exc_catched = TRUE; - goto RETRY_TRY_BLOCK; - } - MRB_END_EXC(&c_jmp); -} - -MRB_API mrb_value -mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) -{ - if (mrb->c->ci->argc < 0) { - return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */ - } - else { - return mrb_vm_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */ - } -} - -MRB_API mrb_value -mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep) -{ - mrb_callinfo *ci; - mrb_value v; - - if (!mrb->c->cibase) { - return mrb_vm_run(mrb, proc, self, stack_keep); - } - if (mrb->c->ci == mrb->c->cibase) { - mrb->c->ci->env = NULL; - return mrb_vm_run(mrb, proc, self, stack_keep); - } - ci = cipush(mrb); - ci->mid = 0; - ci->nregs = 1; /* protect the receiver */ - ci->acc = CI_ACC_SKIP; - ci->target_class = mrb->object_class; - v = mrb_vm_run(mrb, proc, self, stack_keep); - cipop(mrb); - - return v; -} - -#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus) -# if !defined(MRB_ENABLE_CXX_ABI) -} /* end of extern "C" */ -# endif -mrb_int mrb_jmpbuf::jmpbuf_id = 0; -# if !defined(MRB_ENABLE_CXX_ABI) -extern "C" { -# endif -#endif |