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; if (FIXABLE(mrb_float(val))) { 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)) { 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; }
static void pcre_regexp_init(mrb_state *mrb, mrb_value self, mrb_value str, mrb_value flag) { mrb_value regexp; struct mrb_pcre_regexp *reg; int cflag = 0; int erroff = 0; const char *errstr = NULL; regexp = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@regexp")); if (mrb_nil_p(regexp)) { reg = malloc(sizeof(struct mrb_pcre_regexp)); memset(reg, 0, sizeof(struct mrb_pcre_regexp)); mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@regexp"), mrb_obj_value( Data_Wrap_Struct(mrb, mrb->object_class, &mrb_pcre_regexp_type, (void*) reg))); }else{ Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg); pcre_free(reg->re); } if (mrb_nil_p(flag)) cflag = 0; else if (mrb_fixnum_p(flag)) { int nflag = mrb_fixnum(flag); if (nflag & 1) cflag |= PCRE_CASELESS; if (nflag & 2) cflag |= PCRE_EXTENDED; if (nflag & 4) cflag |= PCRE_MULTILINE | PCRE_DOTALL; } else if (mrb_type(flag) == MRB_TT_TRUE) cflag |= PCRE_CASELESS; else if (mrb_string_p(flag)) { if (STRCHR(RSTRING_PTR(flag), 'i')) cflag |= PCRE_CASELESS; if (STRCHR(RSTRING_PTR(flag), 'x')) cflag |= PCRE_EXTENDED; if (STRCHR(RSTRING_PTR(flag), 'm')) cflag |= PCRE_MULTILINE | PCRE_DOTALL; } reg->flag = cflag; reg->re = pcre_compile(RSTRING_PTR(str), cflag, &errstr, &erroff, NULL); if (!reg->re) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' is an invalid regular expression because %S.", mrb_str_new_cstr(mrb, RSTRING_PTR(str) + erroff), mrb_str_new_cstr(mrb, errstr)); } mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@source"), str); }
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"); } }
/* * 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_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)) { long len = ROBJECT_NUMIV(obj); if (len > 0) { mrb_value str; const char *c = mrb_obj_classname(mrb, obj); str = mrb_sprintf(mrb, "-<%s:%p", c, (void*)&obj); return inspect_obj(mrb, obj, str, 0); } return mrb_any_to_s(mrb, obj); } else if (mrb_nil_p(obj)) { return mrb_str_new(mrb, "nil", 3); } return mrb_funcall(mrb, obj, "to_s", 0, 0); }
static void init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) { switch (mrb_type(obj)) { case MRB_TT_CLASS: case MRB_TT_MODULE: copy_class(mrb, dest, obj); /* fall through */ case MRB_TT_OBJECT: case MRB_TT_SCLASS: case MRB_TT_HASH: case MRB_TT_DATA: mrb_iv_copy(mrb, dest, obj); break; default: break; } mrb_funcall(mrb, dest, "initialize_copy", 1, obj); }
static mrb_value hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql) { khash_t(ht) *h1, *h2; if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value(); if (mrb_type(hash2) != MRB_TT_HASH) { if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) { return mrb_false_value(); } if (eql) return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1)); else return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1)); } h1 = RHASH_TBL(hash1); h2 = RHASH_TBL(hash2); if (!h2) { if (!h2) return mrb_true_value(); return mrb_false_value(); } if (!h2) return mrb_false_value(); if (kh_size(h1) != kh_size(h2)) return mrb_false_value(); else { khiter_t k1, k2; mrb_value key; for (k1 = kh_begin(h1); k1 != kh_end(h1); k1++) { if (!kh_exist(h1, k1)) continue; key = kh_key(h1,k1); k2 = kh_get(ht, h2, key); if (k2 != kh_end(h2)) { if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) { continue; /* next key */ } } return mrb_false_value(); } } return mrb_true_value(); }
static mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) { mrb_int idx; 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(mrb, str, indx, 0) != -1) return mrb_str_dup(mrb, indx); return mrb_nil_value(); case MRB_TT_RANGE: /* check if indx is Range */ { mrb_int beg, len; mrb_value tmp; len = RSTRING_LEN_UTF8(str); if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) { tmp = str_subseq(mrb, str, beg, len); return tmp; } else { return mrb_nil_value(); } } default: idx = mrb_fixnum(indx); goto num_index; } return mrb_nil_value(); /* not reached */ }
static mrb_value inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) { int i; mrb_value s, arystr; char head[] = { '[' }; char sep[] = { ',', ' ' }; char tail[] = { ']' }; /* check recursive */ for(i=0; i<RARRAY_LEN(list); i++) { if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) { return mrb_str_new(mrb, "[...]", 5); } } mrb_ary_push(mrb, list, ary); arystr = mrb_str_buf_new(mrb, 64); mrb_str_buf_cat(mrb, arystr, head, sizeof(head)); for(i=0; i<RARRAY_LEN(ary); i++) { int ai = mrb_gc_arena_save(mrb); if (i > 0) { mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep)); } if (mrb_type(RARRAY_PTR(ary)[i]) == MRB_TT_ARRAY) { s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list); } else { s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]); } mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s)); mrb_gc_arena_restore(mrb, ai); } mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail)); mrb_ary_pop(mrb, list); return arystr; }
static mrb_value flo_eq(mrb_state *mrb, mrb_value x) { mrb_value y; volatile mrb_float a, b; mrb_get_args(mrb, "o", &y); switch (mrb_type(y)) { case MRB_TT_FIXNUM: b = (mrb_float)mrb_fixnum(y); break; case MRB_TT_FLOAT: b = mrb_float(y); break; default: return num_equal(mrb, x, y); } a = mrb_float(x); return (a == b)?mrb_true_value():mrb_false_value(); }
static mrb_value ngx_http_mruby_base64_encode(mrb_state *mrb, mrb_value self) { mrb_value mrb_src; ngx_str_t src, dst; mrb_get_args(mrb, "o", &mrb_src); if (mrb_type(mrb_src) != MRB_TT_STRING) { mrb_src = mrb_funcall(mrb, mrb_src, "to_s", 0, NULL); } src.data = (u_char *)RSTRING_PTR(mrb_src); src.len = RSTRING_LEN(mrb_src); dst.len = ngx_base64_encoded_length(src.len); dst.data = mrb_malloc(mrb, dst.len + 1); ngx_encode_base64(&dst, &src); return mrb_str_new(mrb, (char *)dst.data, dst.len); }
void ap_mrb_raise_error(mrb_state *mrb, mrb_value obj, request_rec *r) { struct RString *str; char *err_out; obj = mrb_funcall(mrb, obj, "inspect", 0); if (mrb_type(obj) == MRB_TT_STRING) { str = mrb_str_ptr(obj); err_out = str->ptr; ap_log_rerror(APLOG_MARK , APLOG_ERR , 0 , r , "%s ERROR %s: mrb_run failed. error: %s" , MODULE_NAME , __func__ , err_out ); } }
static size_t get_pool_block_size(mrb_state *mrb, mrb_irep *irep) { size_t size = 0; size_t pool_no; int len; mrb_value str; char buf[32]; 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_fix2str(mrb, irep->pool[pool_no], 10); size += RSTRING_LEN(str); break; case MRB_TT_FLOAT: len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no])); size += len; break; case MRB_TT_STRING: str = mrb_string_value(mrb, &irep->pool[pool_no]); size += RSTRING_LEN(str); break; default: break; } mrb_gc_arena_restore(mrb, ai); } return size; }
static mrb_value method_super_method(mrb_state *mrb, mrb_value self) { mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@recv")); mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass")); mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner")); mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name")); struct RClass *super, *rklass; struct RProc *proc; struct RObject *me; switch (mrb_type(klass)) { case MRB_TT_SCLASS: super = mrb_class_ptr(klass)->super->super; break; case MRB_TT_ICLASS: super = mrb_class_ptr(klass)->super; break; default: super = mrb_class_ptr(owner)->super; break; } proc = method_search_vm(mrb, &super, mrb_symbol(name)); if (!proc) return mrb_nil_value(); rklass = super; while (super->tt == MRB_TT_ICLASS) super = super->c; me = method_object_alloc(mrb, mrb_obj_class(mrb, self)); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@owner"), mrb_obj_value(super)); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@recv"), recv); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@name"), name); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "proc"), mrb_obj_value(proc)); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@klass"), mrb_obj_value(rklass)); return mrb_obj_value(me); }
//convert rbObj in RVector (assumed to be possible!!!) SEXP mrbArray2RVector(mrb_value rbobj) { SEXP ans; mrb_value arr,elt,tmp; //char *name; int n,i; if(!mrb_obj_is_kind_of(mrb,rbobj,mrb->array_class)) { if(!(mrb_obj_is_kind_of(mrb,rbobj,mrb->fixnum_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->float_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->string_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->true_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->false_class))) return R_NilValue; n=1; arr = mrb_ary_new_capa(mrb,1); mrb_ary_push(mrb,arr,rbobj); } else { arr=rbobj; n=RARRAY_LEN(rbobj); } //Rprintf("n=%d\n",n); elt=mrb_ary_entry(arr,0); if(mrb_type(elt)==MRB_TT_FLOAT) { PROTECT(ans=allocVector(REALSXP,n)); for(i=0;i<n;i++) { REAL(ans)[i]=mrb_float(mrb_ary_entry(arr,i)); } } else if(mrb_type(elt)==MRB_TT_FIXNUM) { PROTECT(ans=allocVector(INTSXP,n)); for(i=0;i<n;i++) { INTEGER(ans)[i]=mrb_int(mrb,mrb_ary_entry(arr,i)); } } else if(mrb_type(elt)==MRB_TT_TRUE || mrb_type(elt)==MRB_TT_FALSE) { PROTECT(ans=allocVector(LGLSXP,n)); for(i=0;i<n;i++) { LOGICAL(ans)[i]=(mrb_type(mrb_ary_entry(arr,i))==MRB_TT_FALSE ? FALSE : TRUE); } } else if(mrb_type(elt)==MRB_TT_STRING) { PROTECT(ans=allocVector(STRSXP,n)); for(i=0;i<n;i++) { tmp=mrb_ary_entry(arr,i); SET_STRING_ELT(ans,i,mkChar(mrb_string_value_ptr(mrb,tmp))); } } else ans=R_NilValue; UNPROTECT(1); return ans; }
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; }
mrb_value num_subi_1(int val, mrb_value a, mrb_int b) { switch (mrb_type(a)) { case MRB_TT_FIXNUM: { mrb_int x, y, z; x = mrb_fixnum(a); y = b; z = x - y; if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) { /* integer overflow */ return mrb_float_value((mrb_float)x - (mrb_float)y); } return mrb_fixnum_value(z); } case MRB_TT_FLOAT: return mrb_float_value(mrb_float(a) - (mrb_float)b); default: NOT_REACHABLE(); } }
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(); }
static mrb_value mrb_sce_init(mrb_state *mrb, mrb_value self) { mrb_value c, e2c, m, str; mrb_int n; int argc, no_errno = 0; char buf[20]; argc = mrb_get_args(mrb, "o|i", &m, &n); if (argc == 1) { if (mrb_type(m) == MRB_TT_FIXNUM) { n = mrb_fixnum(m); m = mrb_nil_value(); } else { no_errno = 1; } } if (!no_errno) { e2c = mrb_const_get(mrb, mrb_obj_value(mrb_module_get(mrb, "Errno")), mrb_intern_lit(mrb, "Errno2class")); c = mrb_hash_fetch(mrb, e2c, mrb_fixnum_value(n), mrb_nil_value()); if (!mrb_nil_p(c)) { mrb_basic_ptr(self)->c = mrb_class_ptr(c); str = mrb_str_new_cstr(mrb, strerror(n)); } else { mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "errno"), mrb_fixnum_value(n)); str = mrb_str_new_cstr(mrb, "Unknown error: "); snprintf(buf, sizeof(buf), "%d", (int)n); mrb_str_cat2(mrb, str, buf); } } else { str = mrb_str_new_cstr(mrb, "unknown error"); } if (!mrb_nil_p(m)) { mrb_str_cat2(mrb, str, " - "); mrb_str_append(mrb, str, m); } mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str); return self; }
static uint32_t get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type) { uint32_t size = 0; int pool_no; mrb_value str; char buf[32]; size += MRB_DUMP_SIZE_OF_LONG; /* plen */ size += irep->plen; /* tt(n) */ size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */ size += MRB_DUMP_SIZE_OF_SHORT; /* crc */ size = DUMP_SIZE(size, type); for (pool_no = 0; pool_no < irep->plen; pool_no++) { uint16_t nlen =0; int len; switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: str = mrb_fix2str(mrb, irep->pool[pool_no], 10); size += (uint32_t)RSTRING_LEN(str); break; case MRB_TT_FLOAT: len = mrb_float_to_str( buf, mrb_float(irep->pool[pool_no])); size += (uint32_t)len; break; case MRB_TT_STRING: str = mrb_string_value( mrb, &irep->pool[pool_no]); nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type); size += nlen; break; default: break; } } return size; }
static struct timeval time2timeval(mrb_state *mrb, mrb_value time) { struct timeval t = { 0, 0 }; switch (mrb_type(time)) { case MRB_TT_FIXNUM: t.tv_sec = mrb_fixnum(time); t.tv_usec = 0; break; case MRB_TT_FLOAT: t.tv_sec = mrb_float(time); t.tv_usec = (mrb_float(time) - t.tv_sec) * 1000000.0; break; default: mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } return t; }
static mrb_value mrb_vedis_append_s(mrb_state *mrb, mrb_value key_obj, mrb_value val_obj, vedis *vstore) { int ret; const char *key = NULL; switch (mrb_type(key_obj)) { case MRB_TT_STRING: key = RSTRING_PTR(key_obj); break; case MRB_TT_SYMBOL: key = mrb_sym2name(mrb, mrb_obj_to_sym(mrb, key_obj)); break; default: mrb_raise(mrb, E_RUNTIME_ERROR, "vedis key type is string or symbol"); } val_obj = mrb_obj_as_string(mrb, val_obj); ret = vedis_kv_append(vstore, key, strlen(key), RSTRING_PTR(val_obj), RSTRING_LEN(val_obj)); if (ret != VEDIS_OK) { mrb_vedis_error(mrb, vstore, 0); } return mrb_true_value(); }
static mrb_value mrb_str_byteslice(mrb_state *mrb, mrb_value str) { mrb_value a1; mrb_int len; int argc; argc = mrb_get_args(mrb, "o|i", &a1, &len); if (argc == 2) { return mrb_str_substr(mrb, str, mrb_fixnum(a1), len); } switch (mrb_type(a1)) { case MRB_TT_RANGE: { mrb_int beg; len = RSTRING_LEN(str); switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) { case 0: /* not range */ break; case 1: /* range */ return mrb_str_substr(mrb, str, beg, len); case 2: /* out of range */ mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1); break; } return mrb_nil_value(); } case MRB_TT_FLOAT: a1 = mrb_fixnum_value((mrb_int)mrb_float(a1)); /* fall through */ case MRB_TT_FIXNUM: return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1); default: mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument"); } /* not reached */ return mrb_nil_value(); }
/* * 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; kh_iv_t *h = RCLASS_IV_TBL(self); int i; const char* p; ary = mrb_ary_new(mrb); if (h) { for (i=0;i<kh_end(h);i++) { if (kh_exist(h, i)) { p = mrb_sym2name(mrb, kh_key(h,i)); if (*p == '@') { if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF) mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, p)); } } } } return ary; }
/* * 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); } return mrb_yield_internal(mrb, b, 0, 0, self, c); }
static mrb_value mrb_struct_equal(mrb_state *mrb, mrb_value s) { mrb_value s2; mrb_value *ptr, *ptr2; long i, len; mrb_get_args(mrb, "o", &s2); if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value(); if (mrb_type(s2) != MRB_TT_STRUCT) return mrb_false_value(); if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) return mrb_false_value(); if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) { mrb_bug("inconsistent struct"); /* should never happen */ } ptr = RSTRUCT_PTR(s); ptr2 = RSTRUCT_PTR(s2); len = RSTRUCT_LEN(s); for (i=0; i<len; i++) { if (!mrb_equal(mrb, ptr[i], ptr2[i])) return mrb_false_value(); } return mrb_true_value(); }
/* 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, j; 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=j=0; i<a->len; i++) { if (!mrb_obj_eq(mrb, a->ptr[i], obj)) { a->ptr[j++] = a->ptr[i]; } } a->len = j; }
/* * 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; }
static void mrb_wslay_event_on_msg_recv_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_msg_recv_arg *arg, void *user_data) { mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data; mrb_state *mrb = data->mrb; int ai = mrb_gc_arena_save(mrb); struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; mrb_value argv[4]; argv[0] = mrb_fixnum_value(arg->rsv); argv[1] = MRB_GET_OPCODE(mrb_fixnum_value(arg->opcode)); argv[2] = mrb_str_new(mrb, (const char *) arg->msg, arg->msg_length); argv[3] = MRB_GET_STATUSCODE(mrb_fixnum_value(arg->status_code)); mrb_value on_msg_recv_arg = mrb_obj_new(mrb, mrb_class_get_under(mrb, mrb_module_get_under(mrb, mrb_module_get(mrb, "Wslay"), "Event"), "OnMsgRecvArg"), NELEMS(argv), argv); mrb_assert(mrb_type(data->on_msg_recv_callback) == MRB_TT_PROC); mrb_yield(mrb, data->on_msg_recv_callback, on_msg_recv_arg); mrb_gc_arena_restore(mrb, ai); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); mrb_gc_arena_restore(mrb, ai); MRB_THROW(mrb->jmp); } MRB_END_EXC(&c_jmp); }
/* * 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 */ mrb_value mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) { mrb_sym sym; mrb_value name; khash_t(iv) *h; khiter_t k; mrb_value val; mrb_value Qundef = mrb_undef_value(); mrb_get_args(mrb, "o", &name); sym = mrb_to_id(mrb, name); //if (OBJ_FROZEN(obj)) mrb_error_frozen("object"); //if (!mrb_is_instance_id(id)) { // mrb_name_error(mrb, id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id)); //} switch (mrb_type(self)) { case MRB_TT_OBJECT: case MRB_TT_CLASS: case MRB_TT_MODULE: if (!mrb_obj_ptr(self)->iv) break; h = mrb_obj_ptr(self)->iv; if (!h) break; k = kh_get(iv, h, sym); if (k != kh_end(h)) { val = kh_value(h, k); if (!mrb_obj_equal(mrb, val, Qundef)) { kh_value(h, k) = Qundef; return val; } } break; default: break; } mrb_name_error(mrb, sym, "instance variable %s not defined", mrb_sym2name(mrb, sym)); return mrb_nil_value(); /* not reached */ }
ngx_int_t ngx_mrb_run_body_filter(ngx_http_request_t *r, ngx_mrb_state_t *state, ngx_mrb_code_t *code, ngx_flag_t cached, ngx_http_mruby_ctx_t *ctx) { mrb_value ARGV, mrb_result; ARGV = mrb_ary_new_capa(state->mrb, 1); mrb_ary_push(state->mrb, ARGV, mrb_str_new(state->mrb, (char *)ctx->body, ctx->body_length)); mrb_define_global_const(state->mrb, "ARGV", ARGV); mrb_result = mrb_run(state->mrb, mrb_proc_new(state->mrb, state->mrb->irep[code->n]), mrb_top_self(state->mrb)); if (state->mrb->exc) { if (code->code_type == NGX_MRB_CODE_TYPE_FILE) { ngx_mrb_raise_file_error(state->mrb, mrb_obj_value(state->mrb->exc), r, code->code.file); } else { ngx_mrb_raise_error(state->mrb, mrb_obj_value(state->mrb->exc), r); } mrb_gc_arena_restore(state->mrb, state->ai); if (!cached) { ngx_mrb_irep_clean(r, state, code); ngx_mrb_state_clean(r, state); } return NGX_ERROR; } if (mrb_type(mrb_result) != MRB_TT_STRING) { mrb_result = mrb_funcall(state->mrb, mrb_result, "to_s", 0, NULL); } ctx->body = (u_char *)RSTRING_PTR(mrb_result); ctx->body_length = ngx_strlen(ctx->body); mrb_gc_arena_restore(state->mrb, state->ai); if (!cached) { ngx_mrb_irep_clean(r, state, code); ngx_mrb_state_clean(r, state); } return NGX_OK; }