|  | @@ -187,11 +187,11 @@ static void *appendsubmsg_handler(void *closure, const void *hd) {
 | 
	
		
			
				|  |  |    VALUE subdesc =
 | 
	
		
			
				|  |  |        get_def_obj((void*)submsgdata->md);
 | 
	
		
			
				|  |  |    VALUE subklass = Descriptor_msgclass(subdesc);
 | 
	
		
			
				|  |  | +  MessageHeader* submsg;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass);
 | 
	
		
			
				|  |  |    RepeatedField_push(ary, submsg_rb);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  MessageHeader* submsg;
 | 
	
		
			
				|  |  |    TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
 | 
	
		
			
				|  |  |    return submsg;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -203,14 +203,15 @@ static void *submsg_handler(void *closure, const void *hd) {
 | 
	
		
			
				|  |  |    VALUE subdesc =
 | 
	
		
			
				|  |  |        get_def_obj((void*)submsgdata->md);
 | 
	
		
			
				|  |  |    VALUE subklass = Descriptor_msgclass(subdesc);
 | 
	
		
			
				|  |  | +  VALUE submsg_rb;
 | 
	
		
			
				|  |  | +  MessageHeader* submsg;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
 | 
	
		
			
				|  |  |      DEREF(msg, submsgdata->ofs, VALUE) =
 | 
	
		
			
				|  |  |          rb_class_new_instance(0, NULL, subklass);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  VALUE submsg_rb = DEREF(msg, submsgdata->ofs, VALUE);
 | 
	
		
			
				|  |  | -  MessageHeader* submsg;
 | 
	
		
			
				|  |  | +  submsg_rb = DEREF(msg, submsgdata->ofs, VALUE);
 | 
	
		
			
				|  |  |    TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
 | 
	
		
			
				|  |  |    return submsg;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -266,12 +267,14 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
 | 
	
		
			
				|  |  |        &frame->key_storage);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    VALUE value_field_typeclass = Qnil;
 | 
	
		
			
				|  |  | +  VALUE value;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
 | 
	
		
			
				|  |  |        mapdata->value_field_type == UPB_TYPE_ENUM) {
 | 
	
		
			
				|  |  |      value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  VALUE value = native_slot_get(
 | 
	
		
			
				|  |  | +  value = native_slot_get(
 | 
	
		
			
				|  |  |        mapdata->value_field_type, value_field_typeclass,
 | 
	
		
			
				|  |  |        &frame->value_storage);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -292,15 +295,14 @@ static map_handlerdata_t* new_map_handlerdata(
 | 
	
		
			
				|  |  |      size_t ofs,
 | 
	
		
			
				|  |  |      const upb_msgdef* mapentry_def,
 | 
	
		
			
				|  |  |      Descriptor* desc) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  const upb_fielddef* key_field;
 | 
	
		
			
				|  |  | +  const upb_fielddef* value_field;
 | 
	
		
			
				|  |  |    map_handlerdata_t* hd = ALLOC(map_handlerdata_t);
 | 
	
		
			
				|  |  |    hd->ofs = ofs;
 | 
	
		
			
				|  |  | -  const upb_fielddef* key_field = upb_msgdef_itof(mapentry_def,
 | 
	
		
			
				|  |  | -                                                  MAP_KEY_FIELD);
 | 
	
		
			
				|  |  | +  key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
 | 
	
		
			
				|  |  |    assert(key_field != NULL);
 | 
	
		
			
				|  |  |    hd->key_field_type = upb_fielddef_type(key_field);
 | 
	
		
			
				|  |  | -  const upb_fielddef* value_field = upb_msgdef_itof(mapentry_def,
 | 
	
		
			
				|  |  | -                                                    MAP_VALUE_FIELD);
 | 
	
		
			
				|  |  | +  value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
 | 
	
		
			
				|  |  |    assert(value_field != NULL);
 | 
	
		
			
				|  |  |    hd->value_field_type = upb_fielddef_type(value_field);
 | 
	
		
			
				|  |  |    hd->value_field_subdef = upb_fielddef_subdef(value_field);
 | 
	
	
		
			
				|  | @@ -366,6 +368,8 @@ static void *oneofsubmsg_handler(void *closure,
 | 
	
		
			
				|  |  |    VALUE subdesc =
 | 
	
		
			
				|  |  |        get_def_obj((void*)oneofdata->md);
 | 
	
		
			
				|  |  |    VALUE subklass = Descriptor_msgclass(subdesc);
 | 
	
		
			
				|  |  | +  VALUE submsg_rb;
 | 
	
		
			
				|  |  | +  MessageHeader* submsg;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (oldcase != oneofdata->oneof_case_num ||
 | 
	
		
			
				|  |  |        DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
 | 
	
	
		
			
				|  | @@ -381,8 +385,7 @@ static void *oneofsubmsg_handler(void *closure,
 | 
	
		
			
				|  |  |    DEREF(msg, oneofdata->case_ofs, uint32_t) =
 | 
	
		
			
				|  |  |        oneofdata->oneof_case_num;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  VALUE submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
 | 
	
		
			
				|  |  | -  MessageHeader* submsg;
 | 
	
		
			
				|  |  | +  submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
 | 
	
		
			
				|  |  |    TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
 | 
	
		
			
				|  |  |    return submsg;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -477,8 +480,9 @@ static void add_handlers_for_mapfield(upb_handlers* h,
 | 
	
		
			
				|  |  |                                        Descriptor* desc) {
 | 
	
		
			
				|  |  |    const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
 | 
	
		
			
				|  |  |    map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
 | 
	
		
			
				|  |  | -  upb_handlers_addcleanup(h, hd, free);
 | 
	
		
			
				|  |  |    upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  upb_handlers_addcleanup(h, hd, free);
 | 
	
		
			
				|  |  |    upb_handlerattr_sethandlerdata(&attr, hd);
 | 
	
		
			
				|  |  |    upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
 | 
	
		
			
				|  |  |    upb_handlerattr_uninit(&attr);
 | 
	
	
		
			
				|  | @@ -491,8 +495,9 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
 | 
	
		
			
				|  |  |    const upb_fielddef* key_field = map_entry_key(msgdef);
 | 
	
		
			
				|  |  |    const upb_fielddef* value_field = map_entry_value(msgdef);
 | 
	
		
			
				|  |  |    map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
 | 
	
		
			
				|  |  | -  upb_handlers_addcleanup(h, hd, free);
 | 
	
		
			
				|  |  |    upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  upb_handlers_addcleanup(h, hd, free);
 | 
	
		
			
				|  |  |    upb_handlerattr_sethandlerdata(&attr, hd);
 | 
	
		
			
				|  |  |    upb_handlers_setendmsg(h, endmap_handler, &attr);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -554,6 +559,7 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
 | 
	
		
			
				|  |  |  static void add_handlers_for_message(const void *closure, upb_handlers *h) {
 | 
	
		
			
				|  |  |    const upb_msgdef* msgdef = upb_handlers_msgdef(h);
 | 
	
		
			
				|  |  |    Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef));
 | 
	
		
			
				|  |  | +  upb_msg_field_iter i;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // If this is a mapentry message type, set up a special set of handlers and
 | 
	
		
			
				|  |  |    // bail out of the normal (user-defined) message type handling.
 | 
	
	
		
			
				|  | @@ -570,7 +576,6 @@ static void add_handlers_for_message(const void *closure, upb_handlers *h) {
 | 
	
		
			
				|  |  |      desc->layout = create_layout(desc->msgdef);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  upb_msg_field_iter i;
 | 
	
		
			
				|  |  |    for (upb_msg_field_begin(&i, desc->msgdef);
 | 
	
		
			
				|  |  |         !upb_msg_field_done(&i);
 | 
	
		
			
				|  |  |         upb_msg_field_next(&i)) {
 | 
	
	
		
			
				|  | @@ -622,8 +627,7 @@ const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc,
 | 
	
		
			
				|  |  |    upb_pbdecodermethodopts opts;
 | 
	
		
			
				|  |  |    upb_pbdecodermethodopts_init(&opts, handlers);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  const upb_pbdecodermethod *ret = upb_pbdecodermethod_new(&opts, owner);
 | 
	
		
			
				|  |  | -  return ret;
 | 
	
		
			
				|  |  | +  return upb_pbdecodermethod_new(&opts, owner);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
 | 
	
	
		
			
				|  | @@ -691,28 +695,31 @@ VALUE Message_decode(VALUE klass, VALUE data) {
 | 
	
		
			
				|  |  |    VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
 | 
	
		
			
				|  |  |    Descriptor* desc = ruby_to_Descriptor(descriptor);
 | 
	
		
			
				|  |  |    VALUE msgklass = Descriptor_msgclass(descriptor);
 | 
	
		
			
				|  |  | +  VALUE msg_rb;
 | 
	
		
			
				|  |  | +  MessageHeader* msg;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (TYPE(data) != T_STRING) {
 | 
	
		
			
				|  |  |      rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  VALUE msg_rb = rb_class_new_instance(0, NULL, msgklass);
 | 
	
		
			
				|  |  | -  MessageHeader* msg;
 | 
	
		
			
				|  |  | +  msg_rb = rb_class_new_instance(0, NULL, msgklass);
 | 
	
		
			
				|  |  |    TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
 | 
	
		
			
				|  |  | -  const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
 | 
	
		
			
				|  |  | -  stackenv se;
 | 
	
		
			
				|  |  | -  stackenv_init(&se, "Error occurred during parsing: %s");
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
 | 
	
		
			
				|  |  | +    const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
 | 
	
		
			
				|  |  | +    stackenv se;
 | 
	
		
			
				|  |  | +    upb_sink sink;
 | 
	
		
			
				|  |  | +    upb_pbdecoder* decoder;
 | 
	
		
			
				|  |  | +    stackenv_init(&se, "Error occurred during parsing: %s");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  upb_sink sink;
 | 
	
		
			
				|  |  | -  upb_sink_reset(&sink, h, msg);
 | 
	
		
			
				|  |  | -  upb_pbdecoder* decoder =
 | 
	
		
			
				|  |  | -      upb_pbdecoder_create(&se.env, method, &sink);
 | 
	
		
			
				|  |  | -  upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
 | 
	
		
			
				|  |  | -                    upb_pbdecoder_input(decoder));
 | 
	
		
			
				|  |  | +    upb_sink_reset(&sink, h, msg);
 | 
	
		
			
				|  |  | +    decoder = upb_pbdecoder_create(&se.env, method, &sink);
 | 
	
		
			
				|  |  | +    upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
 | 
	
		
			
				|  |  | +                      upb_pbdecoder_input(decoder));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  stackenv_uninit(&se);
 | 
	
		
			
				|  |  | +    stackenv_uninit(&se);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    return msg_rb;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -729,6 +736,8 @@ VALUE Message_decode_json(VALUE klass, VALUE data) {
 | 
	
		
			
				|  |  |    VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
 | 
	
		
			
				|  |  |    Descriptor* desc = ruby_to_Descriptor(descriptor);
 | 
	
		
			
				|  |  |    VALUE msgklass = Descriptor_msgclass(descriptor);
 | 
	
		
			
				|  |  | +  VALUE msg_rb;
 | 
	
		
			
				|  |  | +  MessageHeader* msg;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (TYPE(data) != T_STRING) {
 | 
	
		
			
				|  |  |      rb_raise(rb_eArgError, "Expected string for JSON data.");
 | 
	
	
		
			
				|  | @@ -737,20 +746,22 @@ VALUE Message_decode_json(VALUE klass, VALUE data) {
 | 
	
		
			
				|  |  |    // convert, because string handlers pass data directly to message string
 | 
	
		
			
				|  |  |    // fields.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  VALUE msg_rb = rb_class_new_instance(0, NULL, msgklass);
 | 
	
		
			
				|  |  | -  MessageHeader* msg;
 | 
	
		
			
				|  |  | +  msg_rb = rb_class_new_instance(0, NULL, msgklass);
 | 
	
		
			
				|  |  |    TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  stackenv se;
 | 
	
		
			
				|  |  | -  stackenv_init(&se, "Error occurred during parsing: %s");
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    stackenv se;
 | 
	
		
			
				|  |  | +    upb_sink sink;
 | 
	
		
			
				|  |  | +    upb_json_parser* parser;
 | 
	
		
			
				|  |  | +    stackenv_init(&se, "Error occurred during parsing: %s");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  upb_sink sink;
 | 
	
		
			
				|  |  | -  upb_sink_reset(&sink, get_fill_handlers(desc), msg);
 | 
	
		
			
				|  |  | -  upb_json_parser* parser = upb_json_parser_create(&se.env, &sink);
 | 
	
		
			
				|  |  | -  upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
 | 
	
		
			
				|  |  | -                    upb_json_parser_input(parser));
 | 
	
		
			
				|  |  | +    upb_sink_reset(&sink, get_fill_handlers(desc), msg);
 | 
	
		
			
				|  |  | +    parser = upb_json_parser_create(&se.env, &sink);
 | 
	
		
			
				|  |  | +    upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
 | 
	
		
			
				|  |  | +                      upb_json_parser_input(parser));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  stackenv_uninit(&se);
 | 
	
		
			
				|  |  | +    stackenv_uninit(&se);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    return msg_rb;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -781,12 +792,12 @@ static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
 | 
	
		
			
				|  |  |                                  size_t len, const upb_bufhandle *handle) {
 | 
	
		
			
				|  |  | -  UPB_UNUSED(hd);
 | 
	
		
			
				|  |  | -  UPB_UNUSED(handle);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    stringsink *sink = _sink;
 | 
	
		
			
				|  |  |    size_t new_size = sink->size;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  UPB_UNUSED(hd);
 | 
	
		
			
				|  |  | +  UPB_UNUSED(handle);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    while (sink->len + len > new_size) {
 | 
	
		
			
				|  |  |      new_size *= 2;
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -840,10 +851,11 @@ static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
 | 
	
		
			
				|  |  | +  upb_sink subsink;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    if (str == Qnil) return;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
 | 
	
		
			
				|  |  | -  upb_sink subsink;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Ensure that the string has the correct encoding. We also check at field-set
 | 
	
		
			
				|  |  |    // time, but the user may have mutated the string object since then.
 | 
	
	
		
			
				|  | @@ -858,11 +870,14 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
 | 
	
		
			
				|  |  |                        int depth) {
 | 
	
		
			
				|  |  | +  upb_sink subsink;
 | 
	
		
			
				|  |  | +  VALUE descriptor;
 | 
	
		
			
				|  |  | +  Descriptor* subdesc;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    if (submsg == Qnil) return;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  upb_sink subsink;
 | 
	
		
			
				|  |  | -  VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
 | 
	
		
			
				|  |  | -  Descriptor* subdesc = ruby_to_Descriptor(descriptor);
 | 
	
		
			
				|  |  | +  descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
 | 
	
		
			
				|  |  | +  subdesc = ruby_to_Descriptor(descriptor);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
 | 
	
		
			
				|  |  |    putmsg(submsg, subdesc, &subsink, depth + 1);
 | 
	
	
		
			
				|  | @@ -871,19 +886,20 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
 | 
	
		
			
				|  |  |                     int depth) {
 | 
	
		
			
				|  |  | -  if (ary == Qnil) return;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    upb_sink subsink;
 | 
	
		
			
				|  |  | +  upb_fieldtype_t type = upb_fielddef_type(f);
 | 
	
		
			
				|  |  | +  upb_selector_t sel = 0;
 | 
	
		
			
				|  |  | +  int size;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (ary == Qnil) return;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  upb_fieldtype_t type = upb_fielddef_type(f);
 | 
	
		
			
				|  |  | -  upb_selector_t sel = 0;
 | 
	
		
			
				|  |  |    if (upb_fielddef_isprimitive(f)) {
 | 
	
		
			
				|  |  |      sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  int size = NUM2INT(RepeatedField_length(ary));
 | 
	
		
			
				|  |  | +  size = NUM2INT(RepeatedField_length(ary));
 | 
	
		
			
				|  |  |    for (int i = 0; i < size; i++) {
 | 
	
		
			
				|  |  |      void* memory = RepeatedField_index_native(ary, i);
 | 
	
		
			
				|  |  |      switch (type) {
 | 
	
	
		
			
				|  | @@ -966,21 +982,25 @@ static void put_ruby_value(VALUE value,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
 | 
	
		
			
				|  |  |                     int depth) {
 | 
	
		
			
				|  |  | -  if (map == Qnil) return;
 | 
	
		
			
				|  |  | -  Map* self = ruby_to_Map(map);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  Map* self;
 | 
	
		
			
				|  |  |    upb_sink subsink;
 | 
	
		
			
				|  |  | +  const upb_fielddef* key_field;
 | 
	
		
			
				|  |  | +  const upb_fielddef* value_field;
 | 
	
		
			
				|  |  | +  Map_iter it;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (map == Qnil) return;
 | 
	
		
			
				|  |  | +  self = ruby_to_Map(map);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
 | 
	
		
			
				|  |  | -  const upb_fielddef* key_field = map_field_key(f);
 | 
	
		
			
				|  |  | -  const upb_fielddef* value_field = map_field_value(f);
 | 
	
		
			
				|  |  | +  key_field = map_field_key(f);
 | 
	
		
			
				|  |  | +  value_field = map_field_value(f);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  Map_iter it;
 | 
	
		
			
				|  |  |    for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) {
 | 
	
		
			
				|  |  |      VALUE key = Map_iter_key(&it);
 | 
	
		
			
				|  |  |      VALUE value = Map_iter_value(&it);
 | 
	
		
			
				|  |  | +    upb_status status;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      upb_sink entry_sink;
 | 
	
		
			
				|  |  |      upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
 | 
	
	
		
			
				|  | @@ -991,7 +1011,6 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
 | 
	
		
			
				|  |  |      put_ruby_value(value, value_field, self->value_type_class, depth + 1,
 | 
	
		
			
				|  |  |                     &entry_sink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    upb_status status;
 | 
	
		
			
				|  |  |      upb_sink_endmsg(&entry_sink, &status);
 | 
	
		
			
				|  |  |      upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -1001,6 +1020,10 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void putmsg(VALUE msg_rb, const Descriptor* desc,
 | 
	
		
			
				|  |  |                     upb_sink *sink, int depth) {
 | 
	
		
			
				|  |  | +  MessageHeader* msg;
 | 
	
		
			
				|  |  | +  upb_msg_field_iter i;
 | 
	
		
			
				|  |  | +  upb_status status;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    upb_sink_startmsg(sink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Protect against cycles (possible because users may freely reassign message
 | 
	
	
		
			
				|  | @@ -1010,10 +1033,8 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
 | 
	
		
			
				|  |  |               "Maximum recursion depth exceeded during encoding.");
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  MessageHeader* msg;
 | 
	
		
			
				|  |  |    TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  upb_msg_field_iter i;
 | 
	
		
			
				|  |  |    for (upb_msg_field_begin(&i, desc->msgdef);
 | 
	
		
			
				|  |  |         !upb_msg_field_done(&i);
 | 
	
		
			
				|  |  |         upb_msg_field_next(&i)) {
 | 
	
	
		
			
				|  | @@ -1085,7 +1106,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  upb_status status;
 | 
	
		
			
				|  |  |    upb_sink_endmsg(sink, &status);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1120,22 +1140,26 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
 | 
	
		
			
				|  |  |    stringsink sink;
 | 
	
		
			
				|  |  |    stringsink_init(&sink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  const upb_handlers* serialize_handlers =
 | 
	
		
			
				|  |  | -      msgdef_pb_serialize_handlers(desc);
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    const upb_handlers* serialize_handlers =
 | 
	
		
			
				|  |  | +        msgdef_pb_serialize_handlers(desc);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  stackenv se;
 | 
	
		
			
				|  |  | -  stackenv_init(&se, "Error occurred during encoding: %s");
 | 
	
		
			
				|  |  | -  upb_pb_encoder* encoder =
 | 
	
		
			
				|  |  | -      upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
 | 
	
		
			
				|  |  | +    stackenv se;
 | 
	
		
			
				|  |  | +    upb_pb_encoder* encoder;
 | 
	
		
			
				|  |  | +    VALUE ret;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0);
 | 
	
		
			
				|  |  | +    stackenv_init(&se, "Error occurred during encoding: %s");
 | 
	
		
			
				|  |  | +    encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  VALUE ret = rb_str_new(sink.ptr, sink.len);
 | 
	
		
			
				|  |  | +    putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  stackenv_uninit(&se);
 | 
	
		
			
				|  |  | -  stringsink_uninit(&sink);
 | 
	
		
			
				|  |  | +    ret = rb_str_new(sink.ptr, sink.len);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  return ret;
 | 
	
		
			
				|  |  | +    stackenv_uninit(&se);
 | 
	
		
			
				|  |  | +    stringsink_uninit(&sink);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return ret;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*
 | 
	
	
		
			
				|  | @@ -1151,21 +1175,24 @@ VALUE Message_encode_json(VALUE klass, VALUE msg_rb) {
 | 
	
		
			
				|  |  |    stringsink sink;
 | 
	
		
			
				|  |  |    stringsink_init(&sink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  const upb_handlers* serialize_handlers =
 | 
	
		
			
				|  |  | -      msgdef_json_serialize_handlers(desc);
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    const upb_handlers* serialize_handlers =
 | 
	
		
			
				|  |  | +        msgdef_json_serialize_handlers(desc);
 | 
	
		
			
				|  |  | +    upb_json_printer* printer;
 | 
	
		
			
				|  |  | +    stackenv se;
 | 
	
		
			
				|  |  | +    VALUE ret;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  stackenv se;
 | 
	
		
			
				|  |  | -  stackenv_init(&se, "Error occurred during encoding: %s");
 | 
	
		
			
				|  |  | -  upb_json_printer* printer =
 | 
	
		
			
				|  |  | -      upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
 | 
	
		
			
				|  |  | +    stackenv_init(&se, "Error occurred during encoding: %s");
 | 
	
		
			
				|  |  | +    printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
 | 
	
		
			
				|  |  | +    putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  VALUE ret = rb_str_new(sink.ptr, sink.len);
 | 
	
		
			
				|  |  | +    ret = rb_str_new(sink.ptr, sink.len);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  stackenv_uninit(&se);
 | 
	
		
			
				|  |  | -  stringsink_uninit(&sink);
 | 
	
		
			
				|  |  | +    stackenv_uninit(&se);
 | 
	
		
			
				|  |  | +    stringsink_uninit(&sink);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  return ret;
 | 
	
		
			
				|  |  | +    return ret;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |