improve shared symbol tables
authorMichael Wallner <mike@php.net>
Mon, 20 Dec 2021 15:43:43 +0000 (16:43 +0100)
committerMichael Wallner <mike@php.net>
Mon, 20 Dec 2021 15:43:43 +0000 (16:43 +0100)
ion.c
ion.stub.php
ion_arginfo.h
ion_private.h
tests/Symbol/Shared/roundtrip.phpt [new file with mode: 0644]
tests/Symbol/Table.phpt

diff --git a/ion.c b/ion.c
index 3dc454a36bd1de5e6ff9755db2661ac75a13dfc5..14261726854de7a6d836052968ca1f894b8589e7 100644 (file)
--- a/ion.c
+++ b/ion.c
@@ -176,10 +176,12 @@ static ZEND_METHOD(ion_Symbol_Table_Shared, __construct)
 
        zend_string *zname;
        zend_long version = 1;
-       ZEND_PARSE_PARAMETERS_START(1, 2)
+       HashTable *ht_sym = NULL;
+       ZEND_PARSE_PARAMETERS_START(1, 3)
                Z_PARAM_STR(zname)
                Z_PARAM_OPTIONAL
                Z_PARAM_LONG(version)
+               Z_PARAM_ARRAY_HT_OR_NULL(ht_sym)
        ZEND_PARSE_PARAMETERS_END();
 
        ION_CHECK(ion_symbol_table_open_with_type(&obj->tab, NULL, ist_SHARED));
@@ -190,6 +192,20 @@ static ZEND_METHOD(ion_Symbol_Table_Shared, __construct)
        ION_CHECK(ion_symbol_table_set_version(obj->tab, version));
 
        php_ion_symbol_table_ctor(obj);
+
+       zval *zsym;
+       if (ht_sym) ZEND_HASH_FOREACH_VAL(ht_sym, zsym)
+       {
+               zend_string *str = zval_get_string(zsym);
+               if (EG(exception)) {
+                       break;
+               }
+
+               ION_STRING is;
+               ION_CHECK(ion_symbol_table_add_symbol(obj->tab, ion_string_from_zend(&is, str), NULL), zend_string_release(str));
+               zend_string_release(str);
+       }
+       ZEND_HASH_FOREACH_END();
 }
 static ZEND_METHOD(ion_Symbol_Table, getMaxId)
 {
index e7a977d7e0597dcb38a8cb76cf278b41ce6df3bd..2e3324308495335e0c612d94437dcb1b059fd14c 100644 (file)
@@ -131,13 +131,15 @@ class Local implements \ion\Symbol\Table {
 
 namespace ion\Symbol\Table;
 class Shared implements \ion\Symbol\Table {
-    private array $symbols = [];
-
     public function __construct(
         public readonly string $name,
         public readonly int $version = 1,
+        ?array $symbols = null,
     ) {}
 
+    /** Internal cache */
+    private array $symbols = [];
+
     /** @alias ion\Symbol\Table::getMaxId */
     public function getMaxId() : int {}
 
@@ -151,6 +153,7 @@ class Shared implements \ion\Symbol\Table {
 
 namespace ion;
 class Catalog implements Countable {
+    /** Internal cache */
     private array $symbolTables = [];
 
     public function __construct() {}
index 3a94e5f1b7fe8bcf6b25dffe747b874b4f9c5cdc..867de8b9f53ae6cd703112b88e895bf20cc81f8b 100644 (file)
@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 943d369644718978b3b990f4345d51bed5f71366 */
+ * Stub hash: 8f4964120dccb00c053325183fda763f64f08b6e */
 
 ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_ion_Symbol_Table_PHP, 0, 0, ion\\Symbol\\Table, 0)
 ZEND_END_ARG_INFO()
@@ -86,6 +86,7 @@ ZEND_END_ARG_INFO()
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Symbol_Table_Shared___construct, 0, 0, 1)
        ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, version, IS_LONG, 0, "1")
+       ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, symbols, IS_ARRAY, 1, "null")
 ZEND_END_ARG_INFO()
 
 #define arginfo_class_ion_Symbol_Table_Shared_getMaxId arginfo_class_ion_Symbol_Enum_toSID
@@ -1297,12 +1298,6 @@ static zend_class_entry *register_class_ion_Symbol_Table_Shared(zend_class_entry
        class_entry = zend_register_internal_class_ex(&ce, NULL);
        zend_class_implements(class_entry, 1, class_entry_ion_Symbol_Table);
 
-       zval property_symbols_default_value;
-       ZVAL_EMPTY_ARRAY(&property_symbols_default_value);
-       zend_string *property_symbols_name = zend_string_init("symbols", sizeof("symbols") - 1, 1);
-       zend_declare_typed_property(class_entry, property_symbols_name, &property_symbols_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
-       zend_string_release(property_symbols_name);
-
        zval property_name_default_value;
        ZVAL_UNDEF(&property_name_default_value);
        zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1);
@@ -1315,6 +1310,12 @@ static zend_class_entry *register_class_ion_Symbol_Table_Shared(zend_class_entry
        zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
        zend_string_release(property_version_name);
 
+       zval property_symbols_default_value;
+       ZVAL_EMPTY_ARRAY(&property_symbols_default_value);
+       zend_string *property_symbols_name = zend_string_init("symbols", sizeof("symbols") - 1, 1);
+       zend_declare_typed_property(class_entry, property_symbols_name, &property_symbols_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
+       zend_string_release(property_symbols_name);
+
        return class_entry;
 }
 
index 342b1646867a5a1fac90335c7b682068de03cc5e..5264b0b0a02309c37a8ad8a1619c5fddce74fff0 100644 (file)
 #include "ionc/ion.h"
 
 #define PHP_ION_SYMBOL_TABLE_VERSION 1
-#define PHP_ION_SYMBOL(e, s) {0, {sizeof(e)-1, (BYTE *) e}, {sizeof(s)-1, (BYTE *) s}},
+#define PHP_ION_SYMBOL(c, s) { \
+       { \
+               0, \
+               { sizeof(s)-1, (BYTE *) s }, \
+               { { 0, NULL }, 0 }, \
+               0 \
+       }, \
+       { sizeof(c)-1, (BYTE *) c } \
+},
 
 typedef struct php_ion_global_symbol {
-       SID id;
+       ION_SYMBOL s;
        ION_STRING e;
-       ION_STRING s;
 } php_ion_global_symbol;
 
 static php_ion_global_symbol g_sym_tab_php_sym[] = {
-       PHP_ION_SYMBOL("PHP", "PHP")
-       PHP_ION_SYMBOL("Reference", "R")
-       PHP_ION_SYMBOL("Backref", "r")
-       PHP_ION_SYMBOL("Property", "p")
-       PHP_ION_SYMBOL("ClassObject", "c")
-       PHP_ION_SYMBOL("CustomObject", "C")
-       PHP_ION_SYMBOL("Object", "o")
-       PHP_ION_SYMBOL("MagicObject", "O")
-       PHP_ION_SYMBOL("Serializable", "S")
+#define PHP_ION_SYMBOL_PHP                             (g_sym_tab_php_sym[0]).s
+       PHP_ION_SYMBOL("PHP",                   "PHP")
+#define PHP_ION_SYMBOL_REFERENCE               (g_sym_tab_php_sym[1]).s
+       PHP_ION_SYMBOL("Reference",             "R")
+#define PHP_ION_SYMBOL_BACKREF                 (g_sym_tab_php_sym[2]).s
+       PHP_ION_SYMBOL("Backref",               "r")
+#define PHP_ION_SYMBOL_PROPERTY                        (g_sym_tab_php_sym[3]).s
+       PHP_ION_SYMBOL("Property",              "p")
+#define PHP_ION_SYMBOL_CLASS_OBJECT            (g_sym_tab_php_sym[4]).s
+       PHP_ION_SYMBOL("ClassObject",   "c")
+#define PHP_ION_SYMBOL_CUSTOM_OBJECT   (g_sym_tab_php_sym[5]).s
+       PHP_ION_SYMBOL("CustomObject",  "C")
+#define PHP_ION_SYMBOL_OBJECT                  (g_sym_tab_php_sym[6]).s
+       PHP_ION_SYMBOL("Object",                "o")
+#define PHP_ION_SYMBOL_MAGIC_OBJECT            (g_sym_tab_php_sym[7]).s
+       PHP_ION_SYMBOL("MagicObject",   "O")
+#define PHP_ION_SYMBOL_SERIALIZEABLE   (g_sym_tab_php_sym[8]).s
+       PHP_ION_SYMBOL("Serializable",  "S")
+#define PHP_ION_SYMBOL_ENUM                            (g_sym_tab_php_sym[9]).s
        PHP_ION_SYMBOL("Enum", "E")
-       {0}
+       {{0}, {0}}
 };
 #undef PHP_ION_SYMBOL
 
@@ -94,11 +111,11 @@ static inline int g_sym_init(void)
        }
        php_ion_global_symbol *ptr = g_sym_tab_php_sym;
        ion_symbol_table_set_version(g_sym_tab_php, PHP_ION_SYMBOL_TABLE_VERSION);
-       ion_symbol_table_set_name(g_sym_tab_php, &ptr->s);
+       ion_symbol_table_set_name(g_sym_tab_php, &ptr->s.value);
        while (ptr->e.value) {
-               ion_symbol_table_add_symbol(g_sym_tab_php, &ptr->s, &ptr->id);
-               g_sym_hash_add(sys_max_id + ptr->id, (const char *) ptr->s.value, ptr->s.length);
-               g_sym_map_add(sys_max_id + ptr->id, (const char *) ptr->e.value, ptr->e.length);
+               ion_symbol_table_add_symbol(g_sym_tab_php, &ptr->s.value, &ptr->s.sid);
+               g_sym_hash_add(sys_max_id + ptr->s.sid, (const char *) ptr->s.value.value, ptr->s.value.length);
+               g_sym_map_add(sys_max_id + ptr->s.sid, (const char *) ptr->e.value, ptr->e.length);
                ++ptr;
        }
        ion_symbol_table_lock(g_sym_tab_php);
@@ -120,6 +137,7 @@ typedef struct php_ion_serializer {
 } php_ion_serializer;
 
 typedef struct php_ion_annotaions {
+       uint8_t shared_symtab:1;
        uint8_t backref:1;
        uint8_t makeref:1;
        uint8_t object_prop:1;
@@ -519,6 +537,27 @@ static inline void php_ion_symbol_zval(ION_SYMBOL *sym_ptr, zval *return_value)
        }
 }
 
+static inline zval *php_ion_global_symbol_fetch_by_enum(zend_string *name)
+{
+       zval *zgs = zend_hash_find(&php_ion_globals.symbol.cache, name);
+       if (!zgs) {
+               zval *zid = zend_hash_find(&g_sym_map, name);
+               if (zid) {
+                       zval *zss = zend_hash_index_find(&g_sym_hash, Z_LVAL_P(zid));
+                       if (zss) {
+                               zval zsym;
+                               object_init_ex(&zsym, ce_Symbol);
+                               php_ion_symbol *sym = php_ion_obj(symbol, Z_OBJ(zsym));
+                               sym->sym.sid = Z_LVAL_P(zid);
+                               sym->value = zval_get_string(zss);
+                               php_ion_symbol_ctor(sym);
+                               zgs = zend_hash_add(&php_ion_globals.symbol.cache, name, &zsym);
+                       }
+               }
+       }
+       return zgs;
+}
+
 php_ion_decl(symbol, Symbol, php_ion_symbol_dtor(obj));
 
 typedef struct php_ion_symbol_table {
@@ -927,8 +966,6 @@ static inline void php_ion_catalog_symbol_table_zval(php_ion_catalog *obj, ION_S
                if (ztab) {
                        zend_string_release(key);
                        RETURN_COPY(ztab);
-               } else {
-                       fprintf(stderr, "FAIL\n");
                }
        }
 
@@ -1007,6 +1044,7 @@ static inline iERR on_context_change(void *context, ION_COLLECTION *imports)
                php_ion_reader *obj = php_ion_obj(reader, context);
                (void) obj;
        }
+       fprintf(stderr, "%s\n", __FUNCTION__);
        return IERR_OK;
 }
 
@@ -1267,7 +1305,7 @@ static inline void php_ion_serializer_php_dtor(php_ion_serializer_php *obj)
 
 static inline void php_ion_serialize_zval(php_ion_serializer *, zval *);
 
-static inline void php_ion_serialize_struct(php_ion_serializer *ser, zend_array *arr, bool props)
+static inline void php_ion_serialize_struct(php_ion_serializer *ser, zend_array *arr, bool unmangle_props, bool annotate_props)
 {
        ION_CHECK(ion_writer_start_container(ser->writer, tid_STRUCT));
 
@@ -1275,20 +1313,23 @@ static inline void php_ion_serialize_struct(php_ion_serializer *ser, zend_array
        zend_ulong h;
        zend_string *k = NULL;
        if (arr) ZEND_HASH_FOREACH_KEY_VAL_IND(arr, h, k, v)
+               char buf[MAX_LENGTH_OF_LONG + 1];
                ION_STRING is;
                if (k) {
                        size_t prop_len;
                        const char *class_name, *prop_name;
-                       if (props && (SUCCESS == zend_unmangle_property_name_ex(k, &class_name, &prop_name, &prop_len)) && class_name) {
-                               ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("p"))));
-                               ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, (char *) class_name, prop_name - class_name - 1)));
+                       if (unmangle_props && (SUCCESS == zend_unmangle_property_name_ex(k, &class_name, &prop_name, &prop_len)) && class_name) {
+                               if (annotate_props) {
+                                       ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, &PHP_ION_SYMBOL_PROPERTY));
+                                       ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, (char *) class_name, prop_name - class_name - 1)));
+                               }
                        } else {
                                prop_name = k->val;
                                prop_len = k->len;
                        }
                        ion_string_assign_cstr(&is, (char *) prop_name, prop_len);
                } else {
-                       char buf[MAX_LENGTH_OF_LONG + 1], *end = buf + sizeof(buf) - 1;
+                       char *end = buf + sizeof(buf) - 1;
                        char *ptr = zend_print_long_to_buf(end, (zend_long) h);
                        ion_string_assign_cstr(&is, ptr, end - ptr);
                }
@@ -1323,7 +1364,7 @@ static inline void php_ion_serialize_array(php_ion_serializer *ser, zend_array *
        if (zend_array_is_list(arr)) {
                php_ion_serialize_list(ser, arr);
        } else {
-               php_ion_serialize_struct(ser, arr, false);
+               php_ion_serialize_struct(ser, arr, false, false);
        }
 }
 
@@ -1336,7 +1377,7 @@ static inline void php_ion_serialize_object_iface(php_ion_serializer *ser, zend_
        ZVAL_OBJ(&tmp, zobject);
        if (SUCCESS == zobject->ce->serialize(&tmp, &buf, &len, NULL)) {
                ION_STRING is;
-               ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("S"))));
+               ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, &PHP_ION_SYMBOL_SERIALIZEABLE));
                ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_from_zend(&is, zobject->ce->name)));
                ION_CHECK(ion_writer_write_string(ser->writer, ion_string_assign_cstr(&is, (char *) buf, len)));
                efree(buf);
@@ -1356,7 +1397,7 @@ static inline void php_ion_serialize_object_magic(php_ion_serializer *ser, zend_
 
        if (IS_ARRAY == Z_TYPE(rv)) {
                ION_STRING is;
-               ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, fn ? "C" : "O", 1)));
+               ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, fn ? &PHP_ION_SYMBOL_CUSTOM_OBJECT : &PHP_ION_SYMBOL_MAGIC_OBJECT));
                ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_from_zend(&is, zobject->ce->name)));
                php_ion_serialize_zval(ser, &rv);
                zval_ptr_dtor(&rv);
@@ -1371,7 +1412,7 @@ static inline void php_ion_serialize_object_magic(php_ion_serializer *ser, zend_
 static inline void php_ion_serialize_object_enum(php_ion_serializer *ser, zend_object *zobject)
 {
        ION_STRING is;
-       ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("E"))));
+       ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, &PHP_ION_SYMBOL_ENUM));
 
        ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_from_zend(&is, zobject->ce->name)));
        zval *z_cname = zend_enum_fetch_case_name(zobject);
@@ -1383,17 +1424,17 @@ static inline void php_ion_serialize_object_std(php_ion_serializer *ser, zend_ob
        ION_STRING is;
 
        if (zobject->ce != zend_standard_class_def) {
-               ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("c"))));
+               ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, &PHP_ION_SYMBOL_CLASS_OBJECT));
                ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_from_zend(&is, zobject->ce->name)));
        } else {
-               ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("o"))));
+               ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, &PHP_ION_SYMBOL_OBJECT));
        }
 
        zval zobj;
        ZVAL_OBJ(&zobj, zobject);
        HashTable *props = zend_get_properties_for(&zobj, ZEND_PROP_PURPOSE_SERIALIZE);
        if (props) {
-               php_ion_serialize_struct(ser, props, true);
+               php_ion_serialize_struct(ser, props, true, true);
                zend_release_properties(props);
        } else {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, IERR_INTERNAL_ERROR,
@@ -1474,15 +1515,33 @@ static inline void php_ion_serialize_object(php_ion_serializer *ser, zend_object
        }
 }
 
+static inline bool php_ion_serialize_system_value(php_ion_serializer *ser, zval *zv)
+{
+       if (1 == php_ion_globals.serializer.level) {
+               if (Z_TYPE_P(zv) == IS_OBJECT) {
+                       if (Z_OBJCE_P(zv) == ce_Symbol_Table_Shared) {
+                               php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(zv));
+                               ION_CHECK_RETURN(true, ion_symbol_table_unload(obj->tab, ser->writer));
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
+
 static inline void php_ion_serialize_refcounted(php_ion_serializer *ser, zval *zv)
 {
+       if (php_ion_serialize_system_value(ser, zv)) {
+               return;
+       }
+
        zend_ulong idx = (zend_ulong) (uintptr_t) Z_COUNTED_P(zv);
 
        ION_STRING is;
        if (zend_hash_index_exists(ser->ids, idx)) {
                zval *num = zend_hash_index_find(ser->ids, idx);
 
-               ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("r"))));
+               ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, &PHP_ION_SYMBOL_BACKREF));
                ION_CHECK(ion_writer_write_int64(ser->writer, Z_LVAL_P(num)));
        } else {
                zval num;
@@ -1507,7 +1566,7 @@ static inline void php_ion_serialize_refcounted(php_ion_serializer *ser, zval *z
                        break;
 
                case IS_REFERENCE:
-                       ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("R"))));
+                       ION_CHECK(ion_writer_add_annotation_symbol(ser->writer, &PHP_ION_SYMBOL_REFERENCE));
                        php_ion_serialize_zval(ser, Z_REFVAL_P(zv));
                        break;
                }
@@ -1914,8 +1973,16 @@ static inline void php_ion_unserialize_struct(php_ion_unserializer *ser, zval *r
                        php_ion_unserialize_object(ser, return_value);
                }
        } else if (!ser->annotations.object_type) {
+               bool is_shared_symtab = ser->annotations.shared_symtab;
                array_init(return_value);
                php_ion_unserialize_hash(ser, return_value);
+               if (is_shared_symtab) {
+                       zval zobj;
+                       object_init_ex(&zobj, ce_Symbol_Table_Shared);
+                       zend_call_known_function(Z_OBJCE(zobj)->constructor, Z_OBJ(zobj), Z_OBJCE(zobj), NULL, 0, NULL, Z_ARRVAL_P(return_value));
+                       zval_ptr_dtor(return_value);
+                       RETURN_COPY_VALUE(&zobj);
+               }
        } else if (ser->annotations.object_type == 'o') {
                object_init(return_value);
                php_ion_unserialize_hash(ser, return_value);
@@ -2039,6 +2106,11 @@ static inline void php_ion_unserialize_annotations(php_ion_unserializer *ser)
                ION_CHECK(ion_reader_get_an_annotation(ser->reader, i, &ann_str));
 
                if (ann_str.length != 1) {
+                       if (ann_str.length == ION_SYS_STRLEN_SHARED_SYMBOL_TABLE) {
+                               if (!memcmp(ann_str.value, ION_SYMBOL_SHARED_SYMBOL_TABLE_BYTES, ION_SYS_STRLEN_SHARED_SYMBOL_TABLE)) {
+                                       ser->annotations.shared_symtab = true;
+                               }
+                       }
                        continue;
                }
 
@@ -2324,24 +2396,3 @@ void php_ion_unserialize(php_ion_unserializer *ser, zval *zdata, zval *return_va
                OBJ_RELEASE(zo_ser);
        }
 }
-
-static inline zval *php_ion_global_symbol_fetch_by_enum(zend_string *name)
-{
-       zval *zgs = zend_hash_find(&php_ion_globals.symbol.cache, name);
-       if (!zgs) {
-               zval *zid = zend_hash_find(&g_sym_map, name);
-               if (zid) {
-                       zval *zss = zend_hash_index_find(&g_sym_hash, Z_LVAL_P(zid));
-                       if (zss) {
-                               zval zsym;
-                               object_init_ex(&zsym, ce_Symbol);
-                               php_ion_symbol *sym = php_ion_obj(symbol, Z_OBJ(zsym));
-                               sym->sym.sid = Z_LVAL_P(zid);
-                               sym->value = zval_get_string(zss);
-                               php_ion_symbol_ctor(sym);
-                               zgs = zend_hash_add(&php_ion_globals.symbol.cache, name, &zsym);
-                       }
-               }
-       }
-       return zgs;
-}
diff --git a/tests/Symbol/Shared/roundtrip.phpt b/tests/Symbol/Shared/roundtrip.phpt
new file mode 100644 (file)
index 0000000..c9e2b93
--- /dev/null
@@ -0,0 +1,47 @@
+--TEST--
+Symbol\Table\Shared/roundtrip
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+$s = '$ion_shared_symbol_table::{name:"shared",version:1,symbols:["foo","bar","baz"]}';
+$t = new ion\Symbol\Table\Shared(name: "shared", symbols: ["foo","bar","baz"]);
+var_dump(
+       ion\serialize(
+               ion\unserialize(
+                       ion\serialize(
+                               ion\unserialize(
+                                       ion\serialize($t)
+                               )
+                       )
+               )
+       )
+);
+
+var_dump(
+       ion\unserialize(
+               ion\serialize(
+                       ion\unserialize(
+                               ion\serialize(
+                                       ion\unserialize($s)
+                               )
+                       )
+               )
+       )
+);
+?>
+DONE
+--EXPECTF--
+TEST
+string(79) "$ion_shared_symbol_table::{name:"shared",version:1,symbols:["foo","bar","baz"]}"
+object(ion\Symbol\Table\Shared)#%d (3) {
+  ["name"]=>
+  string(6) "shared"
+  ["version"]=>
+  int(1)
+  ["symbols":"ion\Symbol\Table\Shared":private]=>
+  array(0) {
+  }
+}
+DONE
index f35bb10e22b69dd15f102e69021105e7a377809b..86d4b05915db07b9c572079af823b50754bb30e4 100644 (file)
@@ -49,22 +49,22 @@ DONE
 TEST
 global
 object(ion\Symbol\Table\Shared)#%d (3) {
-  ["symbols":"ion\Symbol\Table\Shared":private]=>
-  array(0) {
-  }
   ["name"]=>
   string(4) "$ion"
   ["version"]=>
   int(1)
-}
-object(ion\Symbol\Table\Shared)#%d (3) {
   ["symbols":"ion\Symbol\Table\Shared":private]=>
   array(0) {
   }
+}
+object(ion\Symbol\Table\Shared)#%d (3) {
   ["name"]=>
   string(3) "PHP"
   ["version"]=>
   int(1)
+  ["symbols":"ion\Symbol\Table\Shared":private]=>
+  array(0) {
+  }
 }
 object(ion\Symbol)#%d (3) {
   ["value"]=>