static VALUE rb_f_catch(int argc, VALUE *argv) { VALUE tag; int state; VALUE val = Qnil; /* OK */ rb_thread_t *th = GET_THREAD(); rb_control_frame_t *saved_cfp = th->cfp; if (argc == 0) { tag = rb_obj_alloc(rb_cObject); } else { rb_scan_args(argc, argv, "01", &tag); } PUSH_TAG(); th->tag->tag = tag; if ((state = EXEC_TAG()) == 0) { val = rb_yield_0(1, &tag); } else if (state == TAG_THROW && RNODE(th->errinfo)->u1.value == tag) { th->cfp = saved_cfp; val = th->tag->retval; th->errinfo = Qnil; state = 0; } POP_TAG(); if (state) JUMP_TAG(state); return val; }
static VALUE lazy_flat_map_each(VALUE obj) { NODE *memo = RNODE(obj); rb_block_call(memo->u1.value, id_each, 0, 0, lazy_flat_map_i, memo->u2.value); return Qnil; }
static VALUE lazy_drop_while_func(VALUE val, VALUE args, int argc, VALUE *argv) { NODE *memo = RNODE(args); if (!memo->u3.state && !RTEST(rb_yield_values2(argc - 1, &argv[1]))) { memo->u3.state = TRUE; } if (memo->u3.state) { rb_funcall2(argv[0], id_yield, argc - 1, argv + 1); } return Qnil; }
static VALUE lazy_drop_func(VALUE val, VALUE args, int argc, VALUE *argv) { NODE *memo = RNODE(args); if (memo->u3.cnt == 0) { rb_funcall2(argv[0], id_yield, argc - 1, argv + 1); } else { memo->u3.cnt--; } return Qnil; }
static VALUE lazy_take_func(VALUE val, VALUE args, int argc, VALUE *argv) { NODE *memo = RNODE(args); rb_funcall2(argv[0], id_yield, argc - 1, argv + 1); if (--memo->u3.cnt == 0) { return Qundef; } else { return Qnil; } }
static VALUE lazy_flat_map_to_ary(VALUE obj) { NODE *memo = RNODE(obj); VALUE ary = rb_check_array_type(memo->u1.value); if (NIL_P(ary)) { rb_funcall(memo->u2.value, id_yield, 1, memo->u1.value); } else { long i; for (i = 0; i < RARRAY_LEN(ary); i++) { rb_funcall(memo->u2.value, id_yield, 1, RARRAY_PTR(ary)[i]); } } return Qnil; }
static char * load_lock(const char *ftptr) { st_data_t data; st_table *loading_tbl = get_loading_table(); if (!loading_tbl || !st_lookup(loading_tbl, (st_data_t)ftptr, &data)) { /* loading ruby library should be serialized. */ if (!loading_tbl) { GET_VM()->loading_table = loading_tbl = st_init_strtable(); } /* partial state */ ftptr = ruby_strdup(ftptr); data = (st_data_t)rb_thread_shield_new(); st_insert(loading_tbl, (st_data_t)ftptr, data); return (char *)ftptr; } else if (RB_TYPE_P((VALUE)data, T_NODE) && nd_type((VALUE)data) == NODE_MEMO) { NODE *memo = RNODE(data); void (*init)(void) = (void (*)(void))memo->nd_cfnc; data = (st_data_t)rb_thread_shield_new(); st_insert(loading_tbl, (st_data_t)ftptr, data); (*init)(); return (char *)""; } if (RTEST(ruby_verbose)) { rb_warning("loading in progress, circular require considered harmful - %s", ftptr); rb_backtrace_print_to(rb_stderr); } switch (rb_thread_shield_wait((VALUE)data)) { case Qfalse: data = (st_data_t)ftptr; st_insert(loading_tbl, data, (st_data_t)rb_thread_shield_new()); return 0; case Qnil: return 0; } return (char *)ftptr; }
inline uint NODE(lzindex I, uint id) { if (!id) return 0; return Rev(I, getposRevTrie(I.bwdtrie,leftrankRevTrie(I.bwdtrie, RNODE(I,id)))); }
static size_t memsize_of(VALUE obj) { size_t size = 0; if (SPECIAL_CONST_P(obj)) { return 0; } if (FL_TEST(obj, FL_EXIVAR)) { size += rb_generic_ivar_memsize(obj); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: if (!(RBASIC(obj)->flags & ROBJECT_EMBED) && ROBJECT(obj)->as.heap.ivptr) { size += ROBJECT(obj)->as.heap.numiv * sizeof(VALUE); } break; case T_MODULE: case T_CLASS: size += st_memsize(RCLASS_M_TBL(obj)); if (RCLASS_IV_TBL(obj)) { size += st_memsize(RCLASS_IV_TBL(obj)); } if (RCLASS_IV_INDEX_TBL(obj)) { size += st_memsize(RCLASS_IV_INDEX_TBL(obj)); } if (RCLASS(obj)->ptr->iv_tbl) { size += st_memsize(RCLASS(obj)->ptr->iv_tbl); } if (RCLASS(obj)->ptr->const_tbl) { size += st_memsize(RCLASS(obj)->ptr->const_tbl); } size += sizeof(rb_classext_t); break; case T_STRING: size += rb_str_memsize(obj); break; case T_ARRAY: size += rb_ary_memsize(obj); break; case T_HASH: if (RHASH(obj)->ntbl) { size += st_memsize(RHASH(obj)->ntbl); } break; case T_REGEXP: if (RREGEXP(obj)->ptr) { size += onig_memsize(RREGEXP(obj)->ptr); } break; case T_DATA: size += rb_objspace_data_type_memsize(obj); break; case T_MATCH: if (RMATCH(obj)->rmatch) { struct rmatch *rm = RMATCH(obj)->rmatch; size += sizeof(struct re_registers); /* TODO: onig_region_memsize(&rm->regs); */ size += sizeof(struct rmatch_offset) * rm->char_offset_num_allocated; size += sizeof(struct rmatch); } break; case T_FILE: if (RFILE(obj)->fptr) { size += rb_io_memsize(RFILE(obj)->fptr); } break; case T_RATIONAL: case T_COMPLEX: break; case T_ICLASS: /* iClass shares table with the module */ break; case T_FLOAT: break; case T_BIGNUM: if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) { size += RBIGNUM_LEN(obj) * sizeof(BDIGIT); } break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: if (RNODE(obj)->u1.tbl) { /* TODO: xfree(RANY(obj)->as.node.u1.tbl); */ } break; case NODE_ALLOCA: /* TODO: xfree(RANY(obj)->as.node.u1.node); */ ; } break; /* no need to free iv_tbl */ case T_STRUCT: if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 && RSTRUCT(obj)->as.heap.ptr) { size += sizeof(VALUE) * RSTRUCT_LEN(obj); } break; case T_ZOMBIE: break; default: rb_bug("objspace/memsize_of(): unknown data type 0x%x(%p)", BUILTIN_TYPE(obj), (void*)obj); } return size; }
void obj_dump(VALUE obj, yajl_gen gen) { int type; yajl_gen_map_open(gen); yajl_gen_cstr(gen, "_id"); yajl_gen_value(gen, obj); struct obj_track *tracker = NULL; if (st_lookup(objs, (st_data_t)obj, (st_data_t *)&tracker) && BUILTIN_TYPE(obj) != T_NODE) { yajl_gen_cstr(gen, "file"); yajl_gen_cstr(gen, tracker->source); yajl_gen_cstr(gen, "line"); yajl_gen_integer(gen, tracker->line); } yajl_gen_cstr(gen, "type"); switch (type=BUILTIN_TYPE(obj)) { case T_DATA: yajl_gen_cstr(gen, "data"); if (RBASIC(obj)->klass) { yajl_gen_cstr(gen, "class"); yajl_gen_value(gen, RBASIC(obj)->klass); yajl_gen_cstr(gen, "class_name"); VALUE name = rb_classname(RBASIC(obj)->klass); if (RTEST(name)) yajl_gen_cstr(gen, RSTRING(name)->ptr); else yajl_gen_cstr(gen, 0); } break; case T_FILE: yajl_gen_cstr(gen, "file"); break; case T_FLOAT: yajl_gen_cstr(gen, "float"); yajl_gen_cstr(gen, "data"); yajl_gen_double(gen, RFLOAT(obj)->value); break; case T_BIGNUM: yajl_gen_cstr(gen, "bignum"); yajl_gen_cstr(gen, "negative"); yajl_gen_bool(gen, RBIGNUM(obj)->sign == 0); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, RBIGNUM(obj)->len); yajl_gen_cstr(gen, "data"); yajl_gen_string(gen, RBIGNUM(obj)->digits, RBIGNUM(obj)->len); break; case T_MATCH: yajl_gen_cstr(gen, "match"); yajl_gen_cstr(gen, "data"); yajl_gen_value(gen, RMATCH(obj)->str); break; case T_REGEXP: yajl_gen_cstr(gen, "regexp"); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, RREGEXP(obj)->len); yajl_gen_cstr(gen, "data"); yajl_gen_cstr(gen, RREGEXP(obj)->str); break; case T_SCOPE: yajl_gen_cstr(gen, "scope"); struct SCOPE *scope = (struct SCOPE *)obj; if (scope->local_tbl) { int i = 1; int n = scope->local_tbl[0]; VALUE *list = &scope->local_vars[-1]; VALUE cur = *list++; yajl_gen_cstr(gen, "node"); yajl_gen_value(gen, cur); if (n) { yajl_gen_cstr(gen, "variables"); yajl_gen_map_open(gen); while (n--) { cur = *list++; yajl_gen_cstr(gen, scope->local_tbl[i] == 95 ? "_" : rb_id2name(scope->local_tbl[i])); yajl_gen_value(gen, cur); i++; } yajl_gen_map_close(gen); } } break; case T_NODE: yajl_gen_cstr(gen, "node"); yajl_gen_cstr(gen, "node_type"); yajl_gen_cstr(gen, nd_type_str(obj)); yajl_gen_cstr(gen, "file"); yajl_gen_cstr(gen, RNODE(obj)->nd_file); yajl_gen_cstr(gen, "line"); yajl_gen_integer(gen, nd_line(obj)); yajl_gen_cstr(gen, "node_code"); yajl_gen_integer(gen, nd_type(obj)); switch (nd_type(obj)) { case NODE_SCOPE: break; } break; case T_STRING: yajl_gen_cstr(gen, "string"); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, RSTRING(obj)->len); if (FL_TEST(obj, ELTS_SHARED|FL_USER3)) { yajl_gen_cstr(gen, "shared"); yajl_gen_value(gen, RSTRING(obj)->aux.shared); yajl_gen_cstr(gen, "flags"); yajl_gen_array_open(gen); if (FL_TEST(obj, ELTS_SHARED)) yajl_gen_cstr(gen, "elts_shared"); if (FL_TEST(obj, FL_USER3)) yajl_gen_cstr(gen, "str_assoc"); yajl_gen_array_close(gen); } else { yajl_gen_cstr(gen, "data"); yajl_gen_string(gen, (unsigned char *)RSTRING(obj)->ptr, RSTRING(obj)->len); } break; case T_VARMAP: yajl_gen_cstr(gen, "varmap"); struct RVarmap *vars = (struct RVarmap *)obj; if (vars->next) { yajl_gen_cstr(gen, "next"); yajl_gen_value(gen, (VALUE)vars->next); } if (vars->id) { yajl_gen_cstr(gen, "data"); yajl_gen_map_open(gen); yajl_gen_cstr(gen, rb_id2name(vars->id)); yajl_gen_value(gen, vars->val); yajl_gen_map_close(gen); } break; case T_CLASS: case T_MODULE: case T_ICLASS: yajl_gen_cstr(gen, type==T_CLASS ? "class" : type==T_MODULE ? "module" : "iclass"); yajl_gen_cstr(gen, "name"); VALUE name = rb_classname(obj); if (RTEST(name)) yajl_gen_cstr(gen, RSTRING(name)->ptr); else yajl_gen_cstr(gen, 0); yajl_gen_cstr(gen, "super"); yajl_gen_value(gen, RCLASS(obj)->super); yajl_gen_cstr(gen, "super_name"); VALUE super_name = rb_classname(RCLASS(obj)->super); if (RTEST(super_name)) yajl_gen_cstr(gen, RSTRING(super_name)->ptr); else yajl_gen_cstr(gen, 0); if (FL_TEST(obj, FL_SINGLETON)) { yajl_gen_cstr(gen, "singleton"); yajl_gen_bool(gen, 1); } if (RCLASS(obj)->iv_tbl && RCLASS(obj)->iv_tbl->num_entries) { yajl_gen_cstr(gen, "ivars"); yajl_gen_map_open(gen); st_foreach(RCLASS(obj)->iv_tbl, each_ivar, (st_data_t)gen); yajl_gen_map_close(gen); } if (type != T_ICLASS && RCLASS(obj)->m_tbl && RCLASS(obj)->m_tbl->num_entries) { yajl_gen_cstr(gen, "methods"); yajl_gen_map_open(gen); st_foreach(RCLASS(obj)->m_tbl, each_ivar, (st_data_t)gen); yajl_gen_map_close(gen); } break; case T_OBJECT: yajl_gen_cstr(gen, "object"); yajl_gen_cstr(gen, "class"); yajl_gen_value(gen, RBASIC(obj)->klass); yajl_gen_cstr(gen, "class_name"); yajl_gen_cstr(gen, rb_obj_classname(obj)); struct RClass *klass = RCLASS(obj); if (klass->iv_tbl && klass->iv_tbl->num_entries) { yajl_gen_cstr(gen, "ivars"); yajl_gen_map_open(gen); st_foreach(klass->iv_tbl, each_ivar, (st_data_t)gen); yajl_gen_map_close(gen); } break; case T_ARRAY: yajl_gen_cstr(gen, "array"); struct RArray *ary = RARRAY(obj); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, ary->len); if (FL_TEST(obj, ELTS_SHARED)) { yajl_gen_cstr(gen, "shared"); yajl_gen_value(gen, ary->aux.shared); } else if (ary->len) { yajl_gen_cstr(gen, "data"); yajl_gen_array_open(gen); int i; for(i=0; i < ary->len; i++) yajl_gen_value(gen, ary->ptr[i]); yajl_gen_array_close(gen); } break; case T_HASH: yajl_gen_cstr(gen, "hash"); struct RHash *hash = RHASH(obj); yajl_gen_cstr(gen, "length"); if (hash->tbl) yajl_gen_integer(gen, hash->tbl->num_entries); else yajl_gen_integer(gen, 0); yajl_gen_cstr(gen, "default"); yajl_gen_value(gen, hash->ifnone); if (hash->tbl && hash->tbl->num_entries) { yajl_gen_cstr(gen, "data"); //yajl_gen_map_open(gen); yajl_gen_array_open(gen); st_foreach(hash->tbl, each_hash_entry, (st_data_t)gen); yajl_gen_array_close(gen); //yajl_gen_map_close(gen); } break; default: yajl_gen_cstr(gen, "unknown"); } yajl_gen_cstr(gen, "code"); yajl_gen_integer(gen, BUILTIN_TYPE(obj)); yajl_gen_map_close(gen); }