Exemplo n.º 1
0
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");
    }
  }
}
Exemplo n.º 2
0
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");
    }
  }
}
Exemplo n.º 3
0
/*
 * 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;
}
Exemplo n.º 4
0
Arquivo: error.c Projeto: knugie/ruby
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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.");
    }
  }
}
Exemplo n.º 7
0
Arquivo: error.c Projeto: evan/ruby
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);
    }
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
Arquivo: error.c Projeto: knugie/ruby
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);
}
Exemplo n.º 10
0
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));
    }
}
Exemplo n.º 11
0
// 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;
}
Exemplo n.º 12
0
Arquivo: error.c Projeto: knugie/ruby
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);
    }
}
Exemplo n.º 13
0
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;
}