X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=ion_private.h;h=722efe6bd4a4ca63ff9d05c9f20fb20cf0d68373;hb=f27d5e87d6a39a1d4dae84a46fdbfd162b33eade;hp=205c9b81ae03621d4f22887bb79ea76fd225bdf9;hpb=0272ce4a9b54b22f3f39e3b8dd2043ade3f3b697;p=awesomized%2Fext-ion diff --git a/ion_private.h b/ion_private.h index 205c9b8..722efe6 100644 --- a/ion_private.h +++ b/ion_private.h @@ -11,6 +11,7 @@ */ #include "php.h" +#include "ext/standard/php_var.h" #include "ext/date/php_date.h" #if PHP_DEBUG @@ -128,6 +129,26 @@ LOCAL int g_sym_init(void) return SUCCESS; } +static struct { + zend_string *Year, *Month, *Day, *Min, *Sec, *Frac, *MinTZ, *SecTZ, *FracTZ; +} g_intern_str; + +static void g_intern_str_init() +{ +#define NEW_INTERN_STR(s) \ + g_intern_str.s = zend_string_init_interned(#s, sizeof(#s)-1, 1) + NEW_INTERN_STR(Year); + NEW_INTERN_STR(Month); + NEW_INTERN_STR(Day); + NEW_INTERN_STR(Min); + NEW_INTERN_STR(Sec); + NEW_INTERN_STR(Frac); + NEW_INTERN_STR(MinTZ); + NEW_INTERN_STR(SecTZ); + NEW_INTERN_STR(FracTZ); +#undef NEW_INTERN_STR +} + typedef struct php_ion_serializer { ION_WRITER *writer; ION_WRITER_OPTIONS *options; @@ -223,6 +244,7 @@ static zend_class_entry *ce_Symbol_Table_Shared, *ce_Symbol_Table_System, *ce_Timestamp, + *ce_Timestamp_Format, *ce_Timestamp_Precision, *ce_Type, *ce_Unserializer, @@ -368,6 +390,7 @@ LOCAL void *php_ion_obj_ex(void *obj, ptrdiff_t offset) { php_ion_ ## type *old_obj = php_ion_obj(type, std), \ *new_obj = php_ion_obj(type, create_ion_ ## cname(std->ce)); \ php_ion_ ## type ## _copy(new_obj, old_obj); \ + (void) old_obj; \ return &new_obj->std; \ } #define php_ion_register(type, cname, ...) do { \ @@ -381,7 +404,7 @@ LOCAL void *php_ion_obj_ex(void *obj, ptrdiff_t offset) { #define ION_CHECK_RETURN(r, err, ...) do { \ iERR __err = err; \ - if (__err) { \ + if (UNEXPECTED(__err)) { \ zend_throw_exception_ex(spl_ce_RuntimeException, __err, "%s: %s", ion_error_to_str(__err), #err); \ __VA_ARGS__; \ return r; \ @@ -392,14 +415,14 @@ LOCAL void *php_ion_obj_ex(void *obj, ptrdiff_t offset) { ION_CHECK_RETURN(, err, __VA_ARGS__) #define ION_CATCH(...) do { \ - if (EG(exception)) { \ + if (UNEXPECTED(EG(exception))) { \ __VA_ARGS__; \ return; \ } \ } while (0) #define PTR_CHECK_RETURN(ret, ptr, ...) do { \ - if (!(ptr)) { \ + if (UNEXPECTED(!(ptr))) { \ zend_throw_error(NULL, "Uninitialized object"); \ __VA_ARGS__; \ return ret; \ @@ -432,15 +455,6 @@ LOCAL void update_property_obj(zend_object *obj, const char *n, size_t l, zend_o zend_update_property(obj->ce, obj, n, l, &zobj); } -LOCAL zend_object *get_property_obj(zend_object *obj, const char *n, size_t l, int type) -{ - zval tmp, *zv = zend_read_property(obj->ce, obj, n, l, 0, &tmp); - if (zv && type & Z_TYPE_P(zv)) { - return Z_PTR_P(zv); - } - return NULL; -} - #define RETURN_IONTYPE(typ) do { \ zend_object *__zo = php_ion_type_fetch(typ); \ if (UNEXPECTED(!__zo)) { \ @@ -555,7 +569,7 @@ LOCAL void php_ion_symbol_copy(php_ion_symbol *new_obj, php_ion_symbol *old_obj) ion_string_from_zend(&new_obj->sym.value, new_obj->value); } - if ((new_obj->iloc = get_property_obj(&new_obj->std, ZEND_STRL("importLocation"), IS_OBJECT))) { + if ((new_obj->iloc = old_obj->iloc)) { new_obj->sym.import_location = php_ion_obj(symbol_iloc, new_obj->iloc)->loc; } } @@ -619,13 +633,17 @@ LOCAL void php_ion_symbol_table_ctor(php_ion_symbol_table *obj) { OBJ_CHECK(obj); - ION_STRING is; - if (IERR_OK == ion_symbol_table_get_name(obj->tab, &is)) { - zend_update_property_stringl(obj->std.ce, &obj->std, ZEND_STRL("name"), (char *) is.value, is.length); - } - int32_t iv; - if (IERR_OK == ion_symbol_table_get_version(obj->tab, &iv)) { - zend_update_property_long(obj->std.ce, &obj->std, ZEND_STRL("version"), iv); + ION_SYMBOL_TABLE_TYPE typ = ist_EMPTY; + ion_symbol_table_get_type(obj->tab, &typ); + if (typ != ist_LOCAL) { + ION_STRING is; + if (IERR_OK == ion_symbol_table_get_name(obj->tab, &is)) { + zend_update_property_stringl(obj->std.ce, &obj->std, ZEND_STRL("name"), (char *) is.value, is.length); + } + int32_t iv; + if (IERR_OK == ion_symbol_table_get_version(obj->tab, &iv)) { + zend_update_property_long(obj->std.ce, &obj->std, ZEND_STRL("version"), iv); + } } } @@ -833,7 +851,7 @@ LOCAL void php_ion_decimal_dtor(php_ion_decimal *obj) LOCAL void php_ion_decimal_copy(php_ion_decimal *new_obj, php_ion_decimal *old_obj) { zend_objects_clone_members(&new_obj->std, &old_obj->std); - new_obj->ctx = get_property_obj(&new_obj->std, ZEND_STRL("context"), IS_OBJECT); + new_obj->ctx = old_obj->ctx; ION_CHECK(ion_decimal_copy(&new_obj->dec, &old_obj->dec)); } @@ -860,23 +878,34 @@ LOCAL decQuad *ion_ts_frac_from_usec(decQuad *frac, int usec, decContext *ctx) return decQuadDivide(frac, decQuadFromInt32(&us, usec), decQuadFromInt32(µsecs, 1000000), ctx); } +LOCAL zend_string *php_ion_timestamp_format_fetch(zend_string *fmt_case) +{ + return Z_STR_P(zend_enum_fetch_case_value(zend_enum_get_case(ce_Timestamp_Format, fmt_case))); +} + LOCAL zend_string *php_dt_format_from_precision(uint8_t precision) { - switch (precision & 0x7f) { + switch (precision) { + case ION_TS_FRAC | 0x80: + return php_ion_timestamp_format_fetch(g_intern_str.FracTZ); case ION_TS_FRAC: - return zend_string_init(ZEND_STRL("c"), 0); + return php_ion_timestamp_format_fetch(g_intern_str.Frac); + case ION_TS_SEC | 0x80: + return php_ion_timestamp_format_fetch(g_intern_str.SecTZ); case ION_TS_SEC: - return zend_string_init(ZEND_STRL("Y-m-d\\TH:i:sP"), 0); + return php_ion_timestamp_format_fetch(g_intern_str.Sec); + case ION_TS_MIN | 0x80: + return php_ion_timestamp_format_fetch(g_intern_str.MinTZ); case ION_TS_MIN: - return zend_string_init(ZEND_STRL("Y-m-d\\TH:iP"), 0); + return php_ion_timestamp_format_fetch(g_intern_str.Min); case ION_TS_DAY: - return zend_string_init(ZEND_STRL("Y-m-d\\T"), 0); + return php_ion_timestamp_format_fetch(g_intern_str.Day); case ION_TS_MONTH: - return zend_string_init(ZEND_STRL("Y-m\\T"), 0); + return php_ion_timestamp_format_fetch(g_intern_str.Month); case ION_TS_YEAR: - return zend_string_init(ZEND_STRL("Y\\T"), 0); + return php_ion_timestamp_format_fetch(g_intern_str.Year); default: - return zend_string_init(ZEND_STRL("c"), 0); + return ZSTR_CHAR('c'); } } @@ -884,9 +913,12 @@ LOCAL timelib_time* php_time_from_ion(const ION_TIMESTAMP *ts, decContext *ctx, { timelib_time *time = ecalloc(1, sizeof(*time)); - int precision = ION_TS_FRAC; - ion_timestamp_get_precision(ts, &precision); - switch (precision) { + /* defaults */ + time->y = 1970; + time->m = 1; + time->d = 1; + + switch (ts->precision & 0x7f) { case ION_TS_FRAC: time->us = php_usec_from_ion(&ts->fraction, ctx); /* fallthrough */ @@ -908,7 +940,7 @@ LOCAL timelib_time* php_time_from_ion(const ION_TIMESTAMP *ts, decContext *ctx, /* fallthrough */ default: time->z = ts->tz_offset * 60; - if (time->z) { + if (time->z || ts->precision & 0x80) { time->zone_type = TIMELIB_ZONETYPE_OFFSET; } else { time->zone_type = TIMELIB_ZONETYPE_ID; @@ -917,7 +949,7 @@ LOCAL timelib_time* php_time_from_ion(const ION_TIMESTAMP *ts, decContext *ctx, } if (fmt) { - *fmt = php_dt_format_from_precision(precision); + *fmt = php_dt_format_from_precision(ts->precision); } return time; } @@ -929,10 +961,10 @@ LOCAL ION_TIMESTAMP *ion_timestamp_from_php(ION_TIMESTAMP *buf, php_ion_timestam zval tmp; int precision = Z_LVAL_P(zend_read_property(ts->std.ce, &ts->std, ZEND_STRL("precision"), 0, &tmp)); - if (!precision || precision > ION_TS_FRAC) { + if (!precision || precision > (ION_TS_FRAC|0x80)) { zend_throw_exception_ex(spl_ce_InvalidArgumentException, IERR_INVALID_ARG, "Invalid precision (%d) of ion\\Timestamp", precision); - } else switch ((buf->precision = precision)) { + } else switch ((buf->precision = precision) & 0x7f) { case ION_TS_FRAC: ion_ts_frac_from_usec(&buf->fraction, (int) ts->time->us, ctx); /* fallthrough */ @@ -1008,8 +1040,7 @@ LOCAL ION_COLLECTION *php_ion_catalog_collection(php_ion_catalog *cat) LOCAL void php_ion_catalog_copy(php_ion_catalog *new_obj, php_ion_catalog *old_obj) { - // do not clone members; they're only caches - + // do not clone cache members php_ion_catalog_ctor(new_obj); OBJ_CHECK(new_obj); @@ -1084,11 +1115,9 @@ LOCAL void php_ion_catalog_symbol_table_zval(php_ion_catalog *obj, ION_SYMBOL_TA } } - php_error_docref(NULL, E_NOTICE, "Previously unknown ion\\Symbol\\Table encountered: %s", key->val); - object_init_ex(return_value, ce_Symbol_Table_Shared); php_ion_symbol_table *o_tab = php_ion_obj(symbol_table, Z_OBJ_P(return_value)); - OBJ_CHECK(o_tab, zend_string_release(key)); + o_tab->tab = tab; php_ion_symbol_table_ctor(o_tab); if (ztabs) { @@ -1127,9 +1156,9 @@ LOCAL void php_ion_reader_options_copy(php_ion_reader_options *new_obj, php_ion_ zend_objects_clone_members(&new_obj->std, &old_obj->std); new_obj->opt = old_obj->opt; - new_obj->cat = get_property_obj(&new_obj->std, ZEND_STRL("catalog"), IS_OBJECT); - new_obj->dec_ctx = get_property_obj(&new_obj->std, ZEND_STRL("decimalContext"), IS_OBJECT); - new_obj->cb = get_property_obj(&new_obj->std, ZEND_STRL("onContextChange"), IS_OBJECT); + new_obj->cat = old_obj->cat; + new_obj->dec_ctx = old_obj->dec_ctx; + new_obj->cb = old_obj->cb; if (new_obj->cb) { zval zcb; ZVAL_OBJ(&zcb, new_obj->cb); @@ -1264,16 +1293,11 @@ typedef struct php_ion_writer_options { LOCAL void php_ion_writer_options_copy(php_ion_writer_options *new_obj, php_ion_writer_options *old_obj) { - new_obj->opt = old_obj->opt; + zend_objects_clone_members(&new_obj->std, &old_obj->std); - if (old_obj->cat) { - new_obj->cat = old_obj->cat; - GC_ADDREF(new_obj->cat); - } - if (old_obj->dec_ctx) { - new_obj->dec_ctx = old_obj->dec_ctx; - GC_ADDREF(new_obj->dec_ctx); - } + new_obj->opt = old_obj->opt; + new_obj->cat = old_obj->cat; + new_obj->dec_ctx = old_obj->dec_ctx; } LOCAL void php_ion_writer_options_dtor(php_ion_writer_options *obj) @@ -1297,8 +1321,8 @@ typedef struct php_ion_writer { } type; union { struct { - zval val; smart_str str; + struct _ion_user_stream *usr; } buffer; struct { ION_STRING buf; @@ -1324,18 +1348,6 @@ LOCAL iERR php_ion_writer_stream_handler(struct _ion_user_stream *user) return IERR_OK; } -#define REF_STR() do { \ - ZVAL_NEW_STR(ref, obj->buffer.str.s); \ - GC_ADDREF(obj->buffer.str.s); \ -} while (0) - -#define NEW_REF_STR() do {\ - if (Z_STR_P(ref) != obj->buffer.str.s) { \ - zval_ptr_dtor(ref); \ - REF_STR(); \ - } \ -} while(0) - LOCAL void php_ion_writer_stream_init(php_ion_writer *obj, php_ion_writer_options *opt) { PTR_CHECK(obj->stream.ptr); @@ -1344,62 +1356,72 @@ LOCAL void php_ion_writer_stream_init(php_ion_writer *obj, php_ion_writer_option obj->stream.buf.length = opt ? opt->opt.allocation_page_size : 0x1000; obj->stream.buf.value = emalloc(obj->stream.buf.length); } + +LOCAL void php_ion_writer_buffer_offer(php_ion_writer *obj) +{ + if (obj->buffer.usr) { + obj->buffer.usr->curr = (BYTE *) &obj->buffer.str.s->val[obj->buffer.str.s->len]; + obj->buffer.usr->limit = obj->buffer.usr->curr + obj->buffer.str.a - obj->buffer.str.s->len; + } +} + LOCAL void php_ion_writer_buffer_init(php_ion_writer *obj) { - zval *ref = &obj->buffer.val; - ZVAL_DEREF(ref); + smart_str_alloc(&obj->buffer.str, 0, false); + php_ion_writer_buffer_offer(obj); +} - smart_str_alloc(&obj->buffer.str, 0, 0); +LOCAL void php_ion_writer_buffer_reset(php_ion_writer *obj) +{ + smart_str_free(&obj->buffer.str); + memset(&obj->buffer.str, 0, sizeof(obj->buffer.str)); + php_ion_writer_buffer_init(obj); +} + +LOCAL zend_string *php_ion_writer_buffer_copy(php_ion_writer *obj) +{ + if (obj->buffer.usr) { + // ensure that brain-dead ion_stream interface calls us again + obj->buffer.usr->curr = NULL; + obj->buffer.usr->limit = NULL; + } smart_str_0(&obj->buffer.str); - REF_STR(); + return zend_string_copy(obj->buffer.str.s); } -LOCAL void php_ion_writer_buffer_grow(php_ion_writer *obj) +LOCAL void php_ion_writer_buffer_separate(php_ion_writer *obj, bool grow) { - zval *ref = &obj->buffer.val; - ZVAL_DEREF(ref); + // see zend_string_separate and smart_str_erealloc + zend_string *old_str = obj->buffer.str.s; + zend_string *new_str = zend_string_alloc(obj->buffer.str.a << grow, false); + memcpy(new_str->val, old_str->val, new_str->len = old_str->len); + zend_string_release(old_str); + obj->buffer.str.s = new_str; +} - switch (GC_REFCOUNT(obj->buffer.str.s)) { - case 2: - // nothing to do - break; - case 1: - // we've been separated - GC_ADDREF(obj->buffer.str.s); - break; - default: - // we have to separate - fprintf(stderr, "SEPARATE\n"); - obj->buffer.str.s = zend_string_dup(obj->buffer.str.s, 0); - break; +LOCAL void php_ion_writer_buffer_grow(php_ion_writer *obj) +{ + if (obj->buffer.usr && obj->buffer.usr->curr) { + obj->buffer.str.s->len = obj->buffer.usr->curr - (BYTE *) obj->buffer.str.s->val; } - - zend_string *old = obj->buffer.str.s; - GC_DELREF(old); - smart_str_erealloc(&obj->buffer.str, obj->buffer.str.a << 1); - if (old == obj->buffer.str.s) { - GC_ADDREF(old); - } else if(old == Z_STR_P(ref)) { - ZVAL_NULL(ref); + if (obj->buffer.usr && obj->buffer.usr->curr && obj->buffer.usr->curr == obj->buffer.usr->limit) { + if (UNEXPECTED(GC_REFCOUNT(obj->buffer.str.s) > 1)) { + php_ion_writer_buffer_separate(obj, true); + } else { + smart_str_erealloc(&obj->buffer.str, obj->buffer.str.a << 1); + } + } else if (UNEXPECTED(GC_REFCOUNT(obj->buffer.str.s) > 1)) { + php_ion_writer_buffer_separate(obj, false); } - - NEW_REF_STR(); + php_ion_writer_buffer_offer(obj); } + LOCAL iERR php_ion_writer_buffer_handler(struct _ion_user_stream *user) { php_ion_writer *writer = (php_ion_writer *) user->handler_state; - - if (user->curr) { - writer->buffer.str.s->len += user->curr - (BYTE *) &writer->buffer.str.s->val[writer->buffer.str.s->len]; - smart_str_0(&writer->buffer.str); - if (user->limit == user->curr) { - php_ion_writer_buffer_grow(writer); - } - } - user->curr = (BYTE *) &writer->buffer.str.s->val[writer->buffer.str.s->len]; - user->limit = user->curr + writer->buffer.str.a - writer->buffer.str.s->len; - + writer->buffer.usr = user; + php_ion_writer_buffer_grow(writer); return IERR_OK; } @@ -1420,8 +1442,6 @@ LOCAL void php_ion_writer_options_init_shared_imports(php_ion_writer_options *op ION_COLLECTION_NEXT(cur, ptr); if (*ptr) { ION_CHECK(ion_writer_options_add_shared_imports_symbol_tables(&opt->opt, ptr, 1)); - } else { - break; } } } @@ -1476,7 +1496,6 @@ LOCAL void php_ion_writer_dtor(php_ion_writer *obj) smart_str_0(&obj->buffer.str); zend_string_release(obj->buffer.str.s); } - zval_ptr_dtor(&obj->buffer.val); } } @@ -1665,8 +1684,8 @@ LOCAL void php_ion_serialize_object_std(php_ion_serializer *ser, zend_object *zo LOCAL void php_ion_serialize_object_lob(php_ion_serializer *ser, zend_object *zobject) { - zval tmp_type, *type = zend_read_property(NULL, zobject, ZEND_STRL("type"), 0, &tmp_type); - zval tmp_value, *value = zend_read_property(NULL, zobject, ZEND_STRL("value"), 0, &tmp_value); + zval tmp_type, *type = zend_read_property_ex(NULL, zobject, ZSTR_KNOWN(ZEND_STR_TYPE), 0, &tmp_type); + zval tmp_value, *value = zend_read_property_ex(NULL, zobject, ZSTR_KNOWN(ZEND_STR_VALUE), 0, &tmp_value); switch (Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(type)))) { case tid_BLOB_INT: ION_CHECK(ion_writer_write_blob(ser->writer, (BYTE *) Z_STRVAL_P(value), Z_STRLEN_P(value))); @@ -1996,6 +2015,8 @@ LOCAL zval *php_ion_unserialize_class(php_ion_unserializer *ser, zval *return_va LOCAL void php_ion_unserialize_object_enum(php_ion_unserializer *ser, zval *return_value) { zend_string *zs_case = zval_get_string(return_value); + zend_hash_next_index_insert(ser->tmp, return_value); + ZVAL_NULL(return_value); ION_CATCH(); zend_class_entry *ce = zend_lookup_class(ser->annotations.object_class); @@ -2019,13 +2040,18 @@ LOCAL void php_ion_unserialize_object_iface(php_ion_unserializer *ser, zval *ret zend_class_entry *ce = zend_lookup_class(ser->annotations.object_class); if (can_call_iface_unserialize(ser, ce)) { zend_string *s = zval_get_string(return_value); + zend_hash_next_index_insert(ser->tmp, return_value); ZVAL_NULL(return_value); zval *backref = zend_hash_next_index_insert(ser->ids, return_value); if (SUCCESS == ce->unserialize(backref, ce, (BYTE *) s->val, s->len, NULL)) { RETVAL_ZVAL(backref, 0, 0); - } else if (!EG(exception)) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, IERR_INTERNAL_ERROR, - "Failed to unserialize class %s", ce->name->val); + } else { + zval_ptr_dtor(backref); + ZVAL_NULL(backref); + if (!EG(exception)) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, IERR_INTERNAL_ERROR, + "Failed to unserialize class %s", ce->name->val); + } } zend_string_release(s); } else { @@ -2034,25 +2060,47 @@ LOCAL void php_ion_unserialize_object_iface(php_ion_unserializer *ser, zval *ret } } -LOCAL void php_ion_unserialize_field_name(php_ion_unserializer *ser, zend_string **key) +LOCAL void php_ion_unserialize_field_name_ex(php_ion_unserializer *ser, ION_STRING *name, SID *sid) { - // FIXME: symbol table - ION_STRING name; - ION_CHECK(ion_reader_get_field_name(ser->reader, &name)); - if (!name.length) { + ION_CHECK(ion_reader_get_field_name(ser->reader, name)); + if (!name->length) { ION_SYMBOL *is_ptr; ION_CHECK(ion_reader_get_field_name_symbol(ser->reader, &is_ptr)); if (!ION_SYMBOL_IS_NULL(is_ptr) && is_ptr->value.length) { - name = is_ptr->value; - } else if (is_ptr) { - char buf[MAX_LENGTH_OF_LONG + 1 + 1] = {0}, *end = buf + sizeof(buf) - 1, *ptr; - ptr = zend_print_long_to_buf(end, is_ptr->sid); - *--ptr = '$'; - *key = zend_string_init(ptr, end - ptr, 0); - return; + ION_STRING_ASSIGN(name, &is_ptr->value); + } else { + *sid = is_ptr->sid; } } - *key = zend_string_from_ion(&name); +} + +LOCAL void php_ion_unserialize_field_name(php_ion_unserializer *ser, zend_string **key, bool is_prop) +{ + // FIXME: symbol table + ION_STRING name; + SID sid = UNKNOWN_SID; + char buf[MAX_LENGTH_OF_LONG + 1 + 1] = {0}, *end = buf + sizeof(buf) - 1, *ptr; + + php_ion_unserialize_field_name_ex(ser, &name, &sid); + ION_CATCH(); + + switch (name.length) { + case 0: + ptr = zend_print_long_to_buf(end, sid); + *--ptr = '$'; + *key = zend_string_init(ptr, end - ptr, 0); + break; + case 1: + *key = ZSTR_CHAR(*name.value); + break; + default: + if (is_prop) { + *key = zend_string_init_interned((char *) name.value, name.length, 0); + } else { + *key = zend_string_from_ion(&name); + } + break; + } } static void php_ion_unserialize_props(php_ion_unserializer *ser, zval *return_value) @@ -2070,7 +2118,7 @@ static void php_ion_unserialize_props(php_ion_unserializer *ser, zval *return_va } zend_string *key; - php_ion_unserialize_field_name(ser, &key); + php_ion_unserialize_field_name(ser, &key, true); ION_CATCH(); zval zvalue; @@ -2111,7 +2159,7 @@ LOCAL void php_ion_unserialize_hash(php_ion_unserializer *ser, zval *return_valu } zend_string *key; - php_ion_unserialize_field_name(ser, &key); + php_ion_unserialize_field_name(ser, &key, false); ION_CATCH(); zval zvalue; @@ -2169,7 +2217,7 @@ LOCAL void php_ion_unserialize_object(php_ion_unserializer *ser, zval *return_va { // backup possible backref to array returned by magic/custom __serialize() zval *input = zend_hash_next_index_insert(ser->tmp, return_value); - + ZVAL_NULL(return_value); php_ion_unserialize_class(ser, return_value); ION_CATCH(); @@ -2501,7 +2549,6 @@ LOCAL void php_ion_unserialize_zval(php_ion_unserializer *ser, zval *return_valu ION_CHECK(ion_reader_read_ion_symbol(ser->reader, &sym)); php_ion_symbol_zval(&sym, return_value); if (ser->annotations.object_type) { - zend_hash_next_index_insert(ser->tmp, return_value); goto unserialize_struct; } zend_hash_next_index_insert(ser->ids, return_value); @@ -2512,7 +2559,6 @@ LOCAL void php_ion_unserialize_zval(php_ion_unserializer *ser, zval *return_valu ION_CHECK(ion_reader_read_string(ser->reader, &str)); RETVAL_STRINGL((char *) str.value, str.length); if (ser->annotations.object_type) { - zend_hash_next_index_insert(ser->tmp, return_value); goto unserialize_struct; } zend_hash_next_index_insert(ser->ids, return_value); @@ -2522,7 +2568,6 @@ LOCAL void php_ion_unserialize_zval(php_ion_unserializer *ser, zval *return_valu case tid_BLOB_INT: php_ion_reader_read_lob(ser->reader, return_value); if (ser->annotations.object_type) { - zend_hash_next_index_insert(ser->tmp, return_value); goto unserialize_struct; } zend_hash_next_index_insert(ser->ids, return_value); @@ -2608,7 +2653,8 @@ void php_ion_unserialize(php_ion_unserializer *ser, zval *zdata, zval *return_va reader->buffer = zval_get_string(zdata); } else { zend_throw_exception_ex(spl_ce_InvalidArgumentException, IERR_INVALID_ARG, - "Invalid source to unserialize; expected string or resource"); + "Invalid source to unserialize: expected string or resource, got %s", + zend_zval_type_name(zdata)); if (zo_ser) { OBJ_RELEASE(zo_ser); }