static void check_map_field_type(VALUE val, const upb_fielddef* field) { const upb_fielddef* key_field = map_field_key(field); const upb_fielddef* value_field = map_field_value(field); Map* self; if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || RTYPEDDATA_TYPE(val) != &Map_type) { rb_raise(cTypeError, "Expected Map instance"); } self = ruby_to_Map(val); if (self->key_type != upb_fielddef_type(key_field)) { rb_raise(cTypeError, "Map key type does not match field's key type"); } if (self->value_type != upb_fielddef_type(value_field)) { rb_raise(cTypeError, "Map value type does not match field's value type"); } if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE || upb_fielddef_type(value_field) == UPB_TYPE_ENUM) { if (self->value_type_class != get_def_obj(upb_fielddef_subdef(value_field))) { rb_raise(cTypeError, "Map value type has wrong message/enum class"); } } }
static void check_repeated_field_type(VALUE val, const upb_fielddef* field) { RepeatedField* self; assert(upb_fielddef_label(field) == UPB_LABEL_REPEATED); if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || RTYPEDDATA_TYPE(val) != &RepeatedField_type) { rb_raise(cTypeError, "Expected repeated field array"); } self = ruby_to_RepeatedField(val); if (self->field_type != upb_fielddef_type(field)) { rb_raise(cTypeError, "Repeated field array has wrong element type"); } if (self->field_type == UPB_TYPE_MESSAGE) { if (self->field_type_class != Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) { rb_raise(cTypeError, "Repeated field array has wrong message class"); } } if (self->field_type == UPB_TYPE_ENUM) { if (self->field_type_class != EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) { rb_raise(cTypeError, "Repeated field array has wrong enum class"); } } }
/* * call-seq: * RepeatedField.+(other) => repeated field * * Returns a new repeated field that contains the concatenated list of this * repeated field's elements and other's elements. The other (second) list may * be either another repeated field or a Ruby array. */ VALUE RepeatedField_plus(VALUE _self, VALUE list) { VALUE dupped = RepeatedField_dup(_self); if (TYPE(list) == T_ARRAY) { for (int i = 0; i < RARRAY_LEN(list); i++) { VALUE elem = rb_ary_entry(list, i); RepeatedField_push(dupped, elem); } } else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) && RTYPEDDATA_TYPE(list) == &RepeatedField_type) { RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* list_rptfield = ruby_to_RepeatedField(list); if (self->field_type != list_rptfield->field_type || self->field_type_class != list_rptfield->field_type_class) { rb_raise(rb_eArgError, "Attempt to append RepeatedField with different element type."); } for (int i = 0; i < list_rptfield->size; i++) { void* mem = RepeatedField_index_native(list, i); RepeatedField_push_native(dupped, mem); } } else { rb_raise(rb_eArgError, "Unknown type appending to RepeatedField"); } return dupped; }
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type) { if (!RB_TYPE_P(obj, T_DATA) || !RTYPEDDATA_P(obj) || !rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) { return 0; } return 1; }
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type) { if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != T_DATA || !RTYPEDDATA_P(obj) || RTYPEDDATA_TYPE(obj) != data_type) { return 0; } return 1; }
void validate_type_class(upb_fieldtype_t type, VALUE klass) { if (rb_ivar_get(klass, descriptor_instancevar_interned) == Qnil) { rb_raise(rb_eArgError, "Type class has no descriptor. Please pass a " "class or enum as returned by the DescriptorPool."); } if (type == UPB_TYPE_MESSAGE) { VALUE desc = rb_ivar_get(klass, descriptor_instancevar_interned); if (!RB_TYPE_P(desc, T_DATA) || !RTYPEDDATA_P(desc) || RTYPEDDATA_TYPE(desc) != &_Descriptor_type) { rb_raise(rb_eArgError, "Descriptor has an incorrect type."); } if (rb_get_alloc_func(klass) != &Message_alloc) { rb_raise(rb_eArgError, "Message class was not returned by the DescriptorPool."); } } else if (type == UPB_TYPE_ENUM) { VALUE enumdesc = rb_ivar_get(klass, descriptor_instancevar_interned); if (!RB_TYPE_P(enumdesc, T_DATA) || !RTYPEDDATA_P(enumdesc) || RTYPEDDATA_TYPE(enumdesc) != &_EnumDescriptor_type) { rb_raise(rb_eArgError, "Descriptor has an incorrect type."); } } }
void rb_check_type(VALUE x, int t) { const struct types *type = builtin_types; const struct types *const typeend = builtin_types + sizeof(builtin_types) / sizeof(builtin_types[0]); int xt; if (x == Qundef) { rb_bug("undef leaked to the Ruby space"); } xt = TYPE(x); if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) { while (type < typeend) { if (type->type == t) { const char *etype; if (NIL_P(x)) { etype = "nil"; } else if (FIXNUM_P(x)) { etype = "Fixnum"; } else if (SYMBOL_P(x)) { etype = "Symbol"; } else if (rb_special_const_p(x)) { x = rb_obj_as_string(x); etype = StringValuePtr(x); } else { etype = rb_obj_classname(x); } rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", etype, type->name); } type++; } if (xt > T_MASK && xt <= 0x3f) { rb_fatal("unknown type 0x%x (0x%x given, probably comes from extension library for ruby 1.8)", t, xt); } rb_bug("unknown type 0x%x (0x%x given)", t, xt); } }
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type) { const char *etype; static const char mesg[] = "wrong argument type %s (expected %s)"; if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != T_DATA) { Check_Type(obj, T_DATA); } if (!RTYPEDDATA_P(obj)) { etype = rb_obj_classname(obj); rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); } else if (RTYPEDDATA_TYPE(obj) != data_type) { etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name; rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); } return DATA_PTR(obj); }
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type) { const char *etype; static const char mesg[] = "wrong argument type %s (expected %s)"; if (!RB_TYPE_P(obj, T_DATA)) { etype = builtin_class_name(obj); rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); } if (!RTYPEDDATA_P(obj)) { etype = rb_obj_classname(obj); rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); } else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) { etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name; rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); } return DATA_PTR(obj); }
void rb_check_type(VALUE x, int t) { const struct types *type = builtin_types; const struct types *const typeend = builtin_types + sizeof(builtin_types) / sizeof(builtin_types[0]); int xt; if (x == Qundef) { rb_bug("undef leaked to the Ruby space"); } xt = TYPE(x); if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) { while (type < typeend) { if (type->type == t) { const char *etype; if (NIL_P(x)) { etype = "nil"; } else if (FIXNUM_P(x)) { etype = "Fixnum"; } else if (SYMBOL_P(x)) { etype = "Symbol"; } else if (rb_special_const_p(x)) { etype = RSTRING_PTR(rb_obj_as_string(x)); } else { etype = rb_obj_classname(x); } rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", etype, type->name); } type++; } rb_bug("unknown type 0x%x (0x%x given)", t, TYPE(x)); } }
// Used only internally -- shared by #merge and #initialize. VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) { if (TYPE(hashmap) == T_HASH) { rb_hash_foreach(hashmap, merge_into_self_callback, _self); } else if (RB_TYPE_P(hashmap, T_DATA) && RTYPEDDATA_P(hashmap) && RTYPEDDATA_TYPE(hashmap) == &Map_type) { Map* self = ruby_to_Map(_self); Map* other = ruby_to_Map(hashmap); upb_strtable_iter it; if (self->key_type != other->key_type || self->value_type != other->value_type || self->value_type_class != other->value_type_class) { rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types"); } for (upb_strtable_begin(&it, &other->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { // Replace any existing value by issuing a 'remove' operation first. upb_value v; upb_value oldv; upb_strtable_remove2(&self->table, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it), &oldv); v = upb_strtable_iter_value(&it); upb_strtable_insert2(&self->table, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it), v); } } else { rb_raise(rb_eArgError, "Unknown type merging into Map"); } return _self; }
void rb_check_type(VALUE x, int t) { int xt; if (x == Qundef) { rb_bug("undef leaked to the Ruby space"); } xt = TYPE(x); if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) { const char *tname = rb_builtin_type_name(t); if (tname) { rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", builtin_class_name(x), tname); } if (xt > T_MASK && xt <= 0x3f) { rb_fatal("unknown type 0x%x (0x%x given, probably comes from extension library for ruby 1.8)", t, xt); } rb_bug("unknown type 0x%x (0x%x given)", t, xt); } }
VALUE rb_object_free(VALUE obj) { ID id_destructor = rb_intern("__destruct__"); /* value returned by destructor */ VALUE destruct_value = Qnil; /* prevent freeing of immediates */ switch (TYPE(obj)) { case T_NIL: case T_FIXNUM: case T_TRUE: case T_FALSE: case T_SYMBOL: rb_raise(rb_eTypeError, "obj_free() called for immediate value"); break; } /* prevent freeing of *some* critical objects */ if ((obj == rb_cObject) || (obj == rb_cClass) || (obj == rb_cModule) || (obj == rb_cSymbol) || (obj == rb_cFixnum) || (obj == rb_cFloat) || (obj == rb_cString) || (obj == rb_cRegexp) || (obj == rb_cInteger) || (obj == rb_cArray) || (obj == rb_cNilClass) || (obj == rb_cFalseClass) || (obj == rb_cTrueClass) || (obj == rb_cNumeric) || (obj == rb_cBignum) || (obj == rb_cStruct)) rb_raise(rb_eTypeError, "obj_free() called for critical object"); /* run destructor (if one is defined) */ if (rb_respond_to(obj, id_destructor)) destruct_value = rb_funcall(obj, id_destructor, 0); #ifdef RUBY_19 switch (BUILTIN_TYPE(obj)) { case T_NIL: case T_FIXNUM: case T_TRUE: case T_FALSE: rb_bug("obj_free() called for broken object"); break; } if (FL_TEST(obj, FL_EXIVAR)) { rb_free_generic_ivar((VALUE)obj); FL_UNSET(obj, FL_EXIVAR); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) && RANY(obj)->as.object.as.heap.ivptr) { xfree(RANY(obj)->as.object.as.heap.ivptr); } break; case T_MODULE: case T_CLASS: rb_clear_cache_by_class((VALUE)obj); rb_free_m_table(RCLASS_M_TBL(obj)); if (RCLASS_IV_TBL(obj)) { st_free_table(RCLASS_IV_TBL(obj)); } if (RCLASS_IV_INDEX_TBL(obj)) { st_free_table(RCLASS_IV_INDEX_TBL(obj)); } xfree(RANY(obj)->as.klass.ptr); break; case T_STRING: rb_str_free(obj); break; case T_ARRAY: rb_ary_free(obj); break; case T_HASH: if (RANY(obj)->as.hash.ntbl) { st_free_table(RANY(obj)->as.hash.ntbl); } break; case T_REGEXP: if (RANY(obj)->as.regexp.ptr) { onig_free(RANY(obj)->as.regexp.ptr); } break; case T_DATA: if (DATA_PTR(obj)) { if (RTYPEDDATA_P(obj)) { RDATA(obj)->dfree = RANY(obj)->as.typeddata.type->dfree; } if ((long)RANY(obj)->as.data.dfree == -1) { xfree(DATA_PTR(obj)); } else if (RANY(obj)->as.data.dfree) { make_deferred(RANY(obj)); return 1; } } break; case T_MATCH: if (RANY(obj)->as.match.rmatch) { struct rmatch *rm = RANY(obj)->as.match.rmatch; onig_region_free(&rm->regs, 0); if (rm->char_offset) xfree(rm->char_offset); xfree(rm); } break; case T_FILE: if (RANY(obj)->as.file.fptr) { make_io_deferred(RANY(obj)); return 1; } break; case T_RATIONAL: case T_COMPLEX: break; case T_ICLASS: /* iClass shares table with the module */ xfree(RANY(obj)->as.klass.ptr); break; case T_FLOAT: break; case T_BIGNUM: if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) { xfree(RBIGNUM_DIGITS(obj)); } break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: if (RANY(obj)->as.node.u1.tbl) { xfree(RANY(obj)->as.node.u1.tbl); } break; case NODE_ALLOCA: xfree(RANY(obj)->as.node.u1.node); break; } break; /* no need to free iv_tbl */ case T_STRUCT: if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 && RANY(obj)->as.rstruct.as.heap.ptr) { xfree(RANY(obj)->as.rstruct.as.heap.ptr); } break; default: rb_bug("gc_sweep(): unknown data type 0x%x(%p)", BUILTIN_TYPE(obj), (void*)obj); } #else switch (BUILTIN_TYPE(obj)) { case T_NIL: case T_FIXNUM: case T_TRUE: case T_FALSE: rb_bug("obj_free() called for broken object"); break; } if (FL_TEST(obj, FL_EXIVAR)) { rb_free_generic_ivar((VALUE)obj); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); } break; case T_MODULE: case T_CLASS: rb_clear_cache_by_class((VALUE)obj); st_free_table(RANY(obj)->as.klass.m_tbl); if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); } break; case T_STRING: if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); } break; case T_ARRAY: if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); } break; case T_HASH: if (RANY(obj)->as.hash.tbl) { st_free_table(RANY(obj)->as.hash.tbl); } break; case T_REGEXP: if (RANY(obj)->as.regexp.ptr) { re_free_pattern(RANY(obj)->as.regexp.ptr); } if (RANY(obj)->as.regexp.str) { RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); } break; case T_DATA: if (DATA_PTR(obj)) { if ((long)RANY(obj)->as.data.dfree == -1) { RUBY_CRITICAL(free(DATA_PTR(obj))); } else if (RANY(obj)->as.data.dfree) { make_deferred(RANY(obj)); return 1; } } break; case T_MATCH: if (RANY(obj)->as.match.regs) { re_free_registers(RANY(obj)->as.match.regs); RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); } break; case T_FILE: if (RANY(obj)->as.file.fptr) { struct rb_io_t *fptr = RANY(obj)->as.file.fptr; make_deferred(RANY(obj)); RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize; RDATA(obj)->data = fptr; return 1; } break; case T_ICLASS: /* iClass shares table with the module */ break; case T_FLOAT: case T_VARMAP: case T_BLKTAG: break; case T_BIGNUM: if (RANY(obj)->as.bignum.digits) { RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); } break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: if (RANY(obj)->as.node.u1.tbl) { RUBY_CRITICAL(free(RANY(obj)->as.node.u1.tbl)); } break; case NODE_ALLOCA: RUBY_CRITICAL(free(RANY(obj)->as.node.u1.node)); break; } break; /* no need to free iv_tbl */ case T_SCOPE: if (RANY(obj)->as.scope.local_vars && RANY(obj)->as.scope.flags != SCOPE_ALLOCA) { VALUE *vars = RANY(obj)->as.scope.local_vars-1; if (!(RANY(obj)->as.scope.flags & SCOPE_CLONE) && vars[0] == 0) RUBY_CRITICAL(free(RANY(obj)->as.scope.local_tbl)); if ((RANY(obj)->as.scope.flags & (SCOPE_MALLOC|SCOPE_CLONE)) == SCOPE_MALLOC) RUBY_CRITICAL(free(vars)); } break; case T_STRUCT: if (RANY(obj)->as.rstruct.ptr) { RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); } break; default: rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", RANY(obj)->as.basic.flags & T_MASK, obj); } #endif rb_gc_force_recycle(obj); return destruct_value; }