+ RETURN_STR_COPY(sym->value);
+}
+static ZEND_METHOD(ion_Symbol_Enum, toSymbol)
+{
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ zval *zc = zend_enum_fetch_case_name(Z_OBJ_P(ZEND_THIS));
+ PTR_CHECK(zc);
+
+ zval *zsym = php_ion_global_symbol_fetch_by_enum(Z_STR_P(zc));
+ PTR_CHECK(zsym);
+ RETVAL_ZVAL(zsym, 1, 0);
+}
+static ZEND_METHOD(ion_Symbol_Enum, toSID)
+{
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ zval *zc = zend_enum_fetch_case_name(Z_OBJ_P(ZEND_THIS));
+ PTR_CHECK(zc);
+
+ zval *zsym = php_ion_global_symbol_fetch_by_enum(Z_STR_P(zc));
+ PTR_CHECK(zsym);
+
+ zval tmp;
+ RETVAL_ZVAL(zend_read_property(Z_OBJCE_P(zsym), Z_OBJ_P(zsym), ZEND_STRL("sid"), 0, &tmp), 1, 0);
+}
+static ZEND_METHOD(ion_Symbol_Enum, toString)
+{
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ zval *zc = zend_enum_fetch_case_name(Z_OBJ_P(ZEND_THIS));
+ PTR_CHECK(zc);
+
+ zval *zsym = php_ion_global_symbol_fetch_by_enum(Z_STR_P(zc));
+ PTR_CHECK(zsym);
+
+ zval tmp;
+ RETVAL_ZVAL(zend_read_property(Z_OBJCE_P(zsym), Z_OBJ_P(zsym), ZEND_STRL("value"), 0, &tmp), 1, 0);
+}
+static ZEND_METHOD(ion_Symbol_System, asTable)
+{
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ object_init_ex(return_value, ce_Symbol_Table_Shared);
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(return_value));
+ ION_CHECK(ion_symbol_table_get_system_table(&obj->tab, 1));
+ php_ion_symbol_table_ctor(obj);
+ ion_symbol_table_lock(obj->tab);
+}
+static ZEND_METHOD(ion_Symbol_PHP, asTable)
+{
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ object_init_ex(return_value, ce_Symbol_Table_Shared);
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(return_value));
+ obj->tab = g_sym_tab_php;
+ php_ion_symbol_table_ctor(obj);
+ ion_symbol_table_lock(obj->tab);
+}
+static ZEND_METHOD(ion_Symbol_Table_Local, __construct)
+{
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
+ PTR_CHECK(obj);
+
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ ION_CHECK(ion_symbol_table_open_with_type(&obj->tab, NULL, ist_LOCAL));
+ obj->dtor = ion_symbol_table_close;
+ OBJ_CHECK(obj);
+}
+static ZEND_METHOD(ion_Symbol_Table_Local, import)
+{
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
+ OBJ_CHECK(obj);
+
+ zend_object *zo_import;
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJ_OF_CLASS(zo_import, ce_Symbol_Table);
+ ZEND_PARSE_PARAMETERS_END();
+
+ php_ion_symbol_table_import(obj, php_ion_obj(symbol_table, zo_import));
+}
+static ZEND_METHOD(ion_Symbol_Table_Shared, __construct)
+{
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
+ PTR_CHECK(obj);
+
+ zend_string *zname;
+ zend_long version = 1;
+ 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));
+ obj->dtor = ion_symbol_table_close;
+
+ ION_STRING is;
+ ION_CHECK(ion_symbol_table_set_name(obj->tab, ion_string_from_zend(&is, zname)));
+ 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 istr;
+ ION_CHECK(ion_symbol_table_add_symbol(obj->tab, ion_string_from_zend(&istr, str), NULL), zend_string_release(str));
+ zend_string_release(str);
+ }
+ ZEND_HASH_FOREACH_END();
+}
+static ZEND_METHOD(ion_Symbol_Table, getMaxId)
+{
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
+ OBJ_CHECK(obj);
+
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ SID max_sid;
+ ION_CHECK(ion_symbol_table_get_max_sid(obj->tab, &max_sid));
+ RETURN_LONG(max_sid);
+}
+static ZEND_METHOD(ion_Symbol_Table, add)
+{
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
+ OBJ_CHECK(obj);
+
+ zend_object *zo_sym = NULL;
+ zend_string *zs_sym = NULL;
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJ_OF_CLASS_OR_STR(zo_sym, ce_Symbol, zs_sym)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (zo_sym) {
+ zval z_sym;
+ ZVAL_OBJ(&z_sym, zo_sym);
+ zs_sym = zval_get_string(&z_sym);
+ ION_CATCH();
+ }
+ SID sid;
+ ION_STRING is;
+ ION_CHECK(ion_symbol_table_add_symbol(obj->tab, ion_string_from_zend(&is, zs_sym), &sid),
+ if (zo_sym) {
+ zend_string_release(zs_sym);
+ });
+ if (zo_sym) {
+ zend_string_release(zs_sym);
+ }
+ RETURN_LONG(sid);
+}
+static ZEND_METHOD(ion_Symbol_Table, find)
+{
+ php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
+ OBJ_CHECK(obj);
+
+ zend_long zsid;
+ zend_string *zstring = NULL;
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_STR_OR_LONG(zstring, zsid)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (zstring) {
+ SID sid;
+ ION_STRING is;
+ ION_CHECK(ion_symbol_table_find_by_name(obj->tab, ion_string_from_zend(&is, zstring), &sid));
+ zsid = sid;
+ }
+ ION_SYMBOL *sym;
+ ION_CHECK(ion_symbol_table_get_symbol(obj->tab, zsid, &sym));
+ if (sym) {
+ php_ion_symbol_table_symbol_zval(obj, sym, return_value);
+ }