static mrb_value pcre_regexp_initialize_copy(mrb_state *mrb, mrb_value copy) { mrb_value regexp; struct mrb_pcre_regexp *reg; mrb_get_args(mrb, "o", ®exp); if (mrb_obj_equal(mrb, copy, regexp)){ return copy; } if (!mrb_obj_is_instance_of(mrb, regexp, mrb_obj_class(mrb, copy))){ mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg); pcre_regexp_init(mrb, copy, mrb_funcall_argv(mrb, regexp, mrb_intern_lit(mrb, "source"), 0, NULL), mrb_fixnum_value(reg->flag)); return copy; }
static mrb_value convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, int 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", val, mrb_str_new_cstr(mrb, tname)); return mrb_nil_value(); } else { return mrb_nil_value(); } } return mrb_funcall_argv(mrb, val, m, 0, 0); }
static mrb_value hs_regexp_initialize_copy(mrb_state *mrb, mrb_value copy) { mrb_value src; struct mrb_hs_regexp *reg; 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"); } Data_Get_Struct(mrb, src, &mrb_hs_regexp_type, reg); hs_regexp_init(mrb, copy, mrb_funcall_argv(mrb, src, INTERN("source"), 0, NULL), reg->flag); return copy; }
/* * 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_sym id, rtm_id; mrb_bool priv = FALSE, respond_to_p; mrb_get_args(mrb, "n|b", &id, &priv); 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] = mrb_symbol_value(id); 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); }
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_value mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc,...) { mrb_value args[16]; va_list ap; int i; if (argc == 0) { for (i=0; i<5; i++) { args[i] = mrb_nil_value(); } } else { va_start(ap, argc); // assert(argc < 16); for (i=0; i<argc; i++) { args[i] = va_arg(ap, mrb_value); } va_end(ap); } return mrb_funcall_argv(mrb, self, name, argc, args); }
static mrb_value convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, int raise) { mrb_sym m = 0; m = mrb_intern(mrb, method); if (!mrb_respond_to(mrb, val, m)) { if (raise) { mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into %s", mrb_nil_p(val) ? "nil" : (mrb_type(val) == MRB_TT_TRUE) ? "true" : (mrb_type(val) == MRB_TT_FALSE) ? "false" : mrb_obj_classname(mrb, val), tname); return mrb_nil_value(); } else { return mrb_nil_value(); } } return mrb_funcall_argv(mrb, val, m, 0, 0); }
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 = 0; mrb_sym cm; 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 = 1; goto L_RETRY; } c = base; cm = mrb_intern2(mrb, "const_missing", 13); while (c) { if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) { mrb_value name = mrb_symbol_value(sym); return mrb_funcall_argv(mrb, mrb_obj_value(c), cm, 1, &name); } c = c->super; } mrb_raisef(mrb, E_NAME_ERROR, "uninitialized constant %s", mrb_sym2name(mrb, sym)); /* not reached */ return mrb_nil_value(); }
static size_t memfwrite_callback(char* ptr, size_t size, size_t nmemb, void* stream) { MEMFILE* mf = (MEMFILE*) stream; int block = size * nmemb; mrb_value args[2]; mrb_state* mrb = mf->mrb; int ai = mrb_gc_arena_save(mrb); \ if (mf->data && mrb_nil_p(mf->header)) { mrb_value str = mrb_str_new(mrb, mf->data, mf->size); struct RClass* _class_http = mrb_class_get(mrb, "HTTP"); struct RClass* _class_http_parser = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(_class_http), mrb_intern_cstr(mrb, "Parser"))); mrb_value parser = mrb_obj_new(mrb, _class_http_parser, 0, NULL); args[0] = str; mf->header = mrb_funcall_argv(mrb, parser, mrb_intern_cstr(mrb, "parse_response"), 1, args); } args[0] = mf->header; args[1] = mrb_str_new(mrb, ptr, block); mrb_gc_arena_restore(mrb, ai); mrb_yield_argv(mrb, mf->proc, 2, args); return block; }
static mrb_value const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) { struct RClass *c = base; mrb_value v; mrb_bool retry = FALSE; mrb_value name; L_RETRY: while (c) { if (c->iv) { if (iv_get(mrb, c->iv, sym, &v)) return v; } c = c->super; } if (!retry && 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); }
static mrb_value cfunc_call(mrb_state *mrb, mrb_value self) { int margc; mrb_value mresult_type, mname, *margs; void **values = NULL; ffi_type **args = NULL; mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc); void *fp = NULL; if(mrb_string_p(mname) || mrb_symbol_p(mname)) { void *dlh = dlopen(NULL, RTLD_LAZY); fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname)); dlclose(dlh); } else { fp = cfunc_pointer_ptr(mname); } if(fp == NULL) { mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %s", mrb_string_value_ptr(mrb, mname)); goto cfunc_call_exit; } args = malloc(sizeof(ffi_type*) * margc); values = malloc(sizeof(void*) * margc); mrb_sym sym_to_ffi_value = mrb_intern(mrb, "to_ffi_value"); mrb_value nil_ary[1]; nil_ary[0] = mrb_nil_value(); for(int i = 0; i < margc; ++i) { if(mrb_respond_to(mrb, margs[i], sym_to_ffi_value)) { args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value; values[i] = cfunc_pointer_ptr(mrb_funcall_argv(mrb, margs[i], sym_to_ffi_value, 1, nil_ary)); } else { cfunc_mrb_raise_without_jump(mrb, E_TYPE_ERROR, "ignore argument type %s", mrb_obj_classname(mrb, margs[i])); goto cfunc_call_exit; } } ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value; if (result_type == NULL) { cfunc_mrb_raise_without_jump(mrb, E_ARGUMENT_ERROR, "ignore return type %s", mrb_class_name(mrb, mrb_class_ptr(mresult_type))); goto cfunc_call_exit; } mrb_value mresult = mrb_nil_value(); ffi_cif cif; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) { void *result; if(result_type->size > sizeof(long)) { result = malloc(result_type->size); } else if(result_type->size) { result = malloc(sizeof(long)); } else { result = NULL; } ffi_call(&cif, fp, result, values); if(result) { mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, true); mresult = mrb_funcall(mrb, mresult_type, "refer", 1, result_ptr); } } else { mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %s", mname); goto cfunc_call_exit; } cfunc_call_exit: free(values); free(args); return mresult; }
void mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv) { mrb_funcall_argv(mrb, obj, mrb->init_sym, argc, argv); }
void mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv) { mrb_funcall_argv(mrb, obj, "initialize", argc, argv); }
static mrb_value mrb_curl_get(mrb_state *mrb, mrb_value self) { char error[CURL_ERROR_SIZE] = {0}; CURL* curl; CURLcode res = CURLE_OK; MEMFILE* mf; struct RClass* _class_curl; int ssl_verifypeer; struct curl_slist* headerlist = NULL; mrb_value str; struct RClass* _class_http; struct RClass* _class_http_parser; mrb_value parser; mrb_value args[1]; mrb_value url = mrb_nil_value(); mrb_value headers = mrb_nil_value(); mrb_value b = mrb_nil_value(); mrb_get_args(mrb, "S|H&", &url, &headers, &b); if (!mrb_nil_p(headers) && mrb_type(headers) != MRB_TT_HASH) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } mf = memfopen(); curl = curl_easy_init(); _class_curl = mrb_class_get(mrb, "Curl"); ssl_verifypeer = mrb_fixnum(mrb_const_get(mrb, mrb_obj_value(_class_curl), mrb_intern_cstr(mrb, "SSL_VERIFYPEER"))); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ssl_verifypeer); curl_easy_setopt(curl, CURLOPT_URL, RSTRING_PTR(url)); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf); if (mrb_nil_p(b)) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); } else { mf->mrb = mrb; mf->proc = b; mf->header = mrb_nil_value(); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite_callback); } curl_easy_setopt(curl, CURLOPT_HEADERDATA, mf); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, memfwrite); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0); if (!mrb_nil_p(headers)) { mrb_value keys = mrb_hash_keys(mrb, headers); int i, l = RARRAY_LEN(keys); for (i = 0; i < l; i++) { mrb_value key = mrb_ary_entry(keys, i); mrb_value header = mrb_str_dup(mrb, key); mrb_str_cat2(mrb, header, ": "); mrb_str_concat(mrb, header, mrb_hash_get(mrb, headers, key)); headerlist = curl_slist_append(headerlist, RSTRING_PTR(header)); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); } res = curl_easy_perform(curl); if (headerlist) curl_slist_free_all(headerlist); curl_easy_cleanup(curl); if (res != CURLE_OK) { mrb_raise(mrb, E_RUNTIME_ERROR, error); } if (!mrb_nil_p(b)) { return mrb_nil_value(); } str = mrb_str_new(mrb, mf->data, mf->size); memfclose(mf); _class_http = mrb_class_get(mrb, "HTTP"); _class_http_parser = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(_class_http), mrb_intern_cstr(mrb, "Parser"))); parser = mrb_obj_new(mrb, _class_http_parser, 0, NULL); args[0] = str; return mrb_funcall_argv(mrb, parser, mrb_intern_cstr(mrb, "parse_response"), 1, args); }