|
@@ -65,9 +65,10 @@ static bool is_ruby_num(VALUE value) {
|
|
|
TYPE(value) == T_BIGNUM);
|
|
|
}
|
|
|
|
|
|
-void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
|
|
|
+void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE val) {
|
|
|
if (!is_ruby_num(val)) {
|
|
|
- rb_raise(cTypeError, "Expected number type for integral field.");
|
|
|
+ rb_raise(cTypeError, "Expected number type for integral field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(val)));
|
|
|
}
|
|
|
|
|
|
// NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
|
|
@@ -77,13 +78,15 @@ void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
|
|
|
double dbl_val = NUM2DBL(val);
|
|
|
if (floor(dbl_val) != dbl_val) {
|
|
|
rb_raise(rb_eRangeError,
|
|
|
- "Non-integral floating point value assigned to integer field.");
|
|
|
+ "Non-integral floating point value assigned to integer field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(val)));
|
|
|
}
|
|
|
}
|
|
|
if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) {
|
|
|
if (NUM2DBL(val) < 0) {
|
|
|
rb_raise(rb_eRangeError,
|
|
|
- "Assigning negative value to unsigned integer field.");
|
|
|
+ "Assigning negative value to unsigned integer field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(val)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -108,12 +111,14 @@ VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value) {
|
|
|
return value;
|
|
|
}
|
|
|
|
|
|
-void native_slot_set(upb_fieldtype_t type, VALUE type_class,
|
|
|
+void native_slot_set(const char* name,
|
|
|
+ upb_fieldtype_t type, VALUE type_class,
|
|
|
void* memory, VALUE value) {
|
|
|
- native_slot_set_value_and_case(type, type_class, memory, value, NULL, 0);
|
|
|
+ native_slot_set_value_and_case(name, type, type_class, memory, value, NULL, 0);
|
|
|
}
|
|
|
|
|
|
-void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
+void native_slot_set_value_and_case(const char* name,
|
|
|
+ upb_fieldtype_t type, VALUE type_class,
|
|
|
void* memory, VALUE value,
|
|
|
uint32_t* case_memory,
|
|
|
uint32_t case_number) {
|
|
@@ -124,13 +129,15 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
switch (type) {
|
|
|
case UPB_TYPE_FLOAT:
|
|
|
if (!is_ruby_num(value)) {
|
|
|
- rb_raise(cTypeError, "Expected number type for float field.");
|
|
|
+ rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(value)));
|
|
|
}
|
|
|
DEREF(memory, float) = NUM2DBL(value);
|
|
|
break;
|
|
|
case UPB_TYPE_DOUBLE:
|
|
|
if (!is_ruby_num(value)) {
|
|
|
- rb_raise(cTypeError, "Expected number type for double field.");
|
|
|
+ rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(value)));
|
|
|
}
|
|
|
DEREF(memory, double) = NUM2DBL(value);
|
|
|
break;
|
|
@@ -141,7 +148,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
} else if (value == Qfalse) {
|
|
|
val = 0;
|
|
|
} else {
|
|
|
- rb_raise(cTypeError, "Invalid argument for boolean field.");
|
|
|
+ rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(value)));
|
|
|
}
|
|
|
DEREF(memory, int8_t) = val;
|
|
|
break;
|
|
@@ -150,7 +158,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
if (CLASS_OF(value) == rb_cSymbol) {
|
|
|
value = rb_funcall(value, rb_intern("to_s"), 0);
|
|
|
} else if (CLASS_OF(value) != rb_cString) {
|
|
|
- rb_raise(cTypeError, "Invalid argument for string field.");
|
|
|
+ rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(value)));
|
|
|
}
|
|
|
|
|
|
DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
|
|
@@ -158,7 +167,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
|
|
|
case UPB_TYPE_BYTES: {
|
|
|
if (CLASS_OF(value) != rb_cString) {
|
|
|
- rb_raise(cTypeError, "Invalid argument for string field.");
|
|
|
+ rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).",
|
|
|
+ name, rb_class2name(CLASS_OF(value)));
|
|
|
}
|
|
|
|
|
|
DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
|
|
@@ -169,8 +179,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
value = Qnil;
|
|
|
} else if (CLASS_OF(value) != type_class) {
|
|
|
rb_raise(cTypeError,
|
|
|
- "Invalid type %s to assign to submessage field.",
|
|
|
- rb_class2name(CLASS_OF(value)));
|
|
|
+ "Invalid type %s to assign to submessage field '%s'.",
|
|
|
+ rb_class2name(CLASS_OF(value)), name);
|
|
|
}
|
|
|
DEREF(memory, VALUE) = value;
|
|
|
break;
|
|
@@ -181,18 +191,18 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
value = rb_funcall(value, rb_intern("to_sym"), 0);
|
|
|
} else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
|
|
|
rb_raise(cTypeError,
|
|
|
- "Expected number or symbol type for enum field.");
|
|
|
+ "Expected number or symbol type for enum field '%s'.", name);
|
|
|
}
|
|
|
if (TYPE(value) == T_SYMBOL) {
|
|
|
// Ensure that the given symbol exists in the enum module.
|
|
|
VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
|
|
|
if (lookup == Qnil) {
|
|
|
- rb_raise(rb_eRangeError, "Unknown symbol value for enum field.");
|
|
|
+ rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
|
|
|
} else {
|
|
|
int_val = NUM2INT(lookup);
|
|
|
}
|
|
|
} else {
|
|
|
- native_slot_check_int_range_precision(UPB_TYPE_INT32, value);
|
|
|
+ native_slot_check_int_range_precision(name, UPB_TYPE_INT32, value);
|
|
|
int_val = NUM2INT(value);
|
|
|
}
|
|
|
DEREF(memory, int32_t) = int_val;
|
|
@@ -202,7 +212,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
|
case UPB_TYPE_INT64:
|
|
|
case UPB_TYPE_UINT32:
|
|
|
case UPB_TYPE_UINT64:
|
|
|
- native_slot_check_int_range_precision(type, value);
|
|
|
+ native_slot_check_int_range_precision(name, type, value);
|
|
|
switch (type) {
|
|
|
case UPB_TYPE_INT32:
|
|
|
DEREF(memory, int32_t) = NUM2INT(value);
|
|
@@ -658,8 +668,9 @@ void layout_clear(MessageLayout* layout,
|
|
|
|
|
|
DEREF(memory, VALUE) = ary;
|
|
|
} else {
|
|
|
- native_slot_set(upb_fielddef_type(field), field_type_class(field),
|
|
|
- memory, layout_get_default(field));
|
|
|
+ native_slot_set(upb_fielddef_name(field),
|
|
|
+ upb_fielddef_type(field), field_type_class(field),
|
|
|
+ memory, layout_get_default(field));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -816,6 +827,7 @@ void layout_set(MessageLayout* layout,
|
|
|
// use native_slot_set_value_and_case(), which ensures that both the value
|
|
|
// and case number are altered atomically (w.r.t. the Ruby VM).
|
|
|
native_slot_set_value_and_case(
|
|
|
+ upb_fielddef_name(field),
|
|
|
upb_fielddef_type(field), field_type_class(field),
|
|
|
memory, val,
|
|
|
oneof_case, upb_fielddef_number(field));
|
|
@@ -827,8 +839,9 @@ void layout_set(MessageLayout* layout,
|
|
|
check_repeated_field_type(val, field);
|
|
|
DEREF(memory, VALUE) = val;
|
|
|
} else {
|
|
|
- native_slot_set(upb_fielddef_type(field), field_type_class(field), memory,
|
|
|
- val);
|
|
|
+ native_slot_set(upb_fielddef_name(field),
|
|
|
+ upb_fielddef_type(field), field_type_class(field),
|
|
|
+ memory, val);
|
|
|
}
|
|
|
|
|
|
if (layout->fields[upb_fielddef_index(field)].hasbit !=
|