+#if PHP_DEBUG
+# define LOCAL static
+#else
+# define LOCAL static inline
+#endif
+
+#define DECNUMDIGITS 34 /* DECQUAD_Pmax */
+#include "ionc/ion.h"
+
+#define PHP_ION_SYMBOL_TABLE_VERSION 1
+#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 {
+ ION_SYMBOL s;
+ ION_STRING e;
+} php_ion_global_symbol;
+
+static php_ion_global_symbol g_sym_tab_php_sym[] = {
+#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}}
+};
+#undef PHP_ION_SYMBOL
+
+static ION_SYMBOL_TABLE *g_sym_tab_php;
+
+/* [SID => STRING, STRING => SID] */
+static HashTable g_sym_hash;
+/* [enum_case_name => SID] */
+static HashTable g_sym_map;
+
+#define ION_SYS_SYMBOL_SYMBOL_TABLE \
+ ION_SYS_SYMBOL_ION_SYMBOL_TABLE
+#define g_sym_add(enum_name, c_name) do { \
+ g_sym_hash_add(ION_SYS_SID_ ## c_name, ION_SYS_SYMBOL_ ## c_name, ION_SYS_STRLEN_ ## c_name); \
+ g_sym_map_add(ION_SYS_SID_ ## c_name, enum_name, sizeof(enum_name)-1); \
+} while (0)
+
+LOCAL void g_sym_hash_add(int sid, const char *str, size_t len)
+{
+ zval zl, zs;
+ ZVAL_LONG(&zl, sid);
+ ZVAL_STR(&zs, zend_string_init_interned(str, len ,1));
+ zend_hash_add(&g_sym_hash, Z_STR(zs), &zl);
+ zend_hash_index_add(&g_sym_hash, sid, &zs);
+}
+
+LOCAL void g_sym_map_add(int sid, const char *str, size_t len)
+{
+ zval zv;
+ ZVAL_LONG(&zv, sid);
+ zend_hash_str_add(&g_sym_map, str, len, &zv);
+}
+
+LOCAL int g_sym_init(void)
+{
+ zend_hash_init(&g_sym_hash, 0, NULL, NULL, 1);
+ zend_hash_init(&g_sym_map, 0, NULL, NULL, 1);
+
+ g_sym_hash_add(0, ZEND_STRL(""));
+ g_sym_map_add(0, ZEND_STRL(""));
+ g_sym_add("Ion", ION);
+ g_sym_add("Ivm_1_0", IVM);
+ g_sym_add("IonSymbolTable", SYMBOL_TABLE);
+ g_sym_add("Name", NAME);
+ g_sym_add("Version", VERSION);
+ g_sym_add("Imports", IMPORTS);
+ g_sym_add("Symbols", SYMBOLS);
+ g_sym_add("MaxId", MAX_ID);
+ g_sym_add("SharedSymbolTable", SHARED_SYMBOL_TABLE);
+
+ int sys_max_id = ION_SYS_SID_SHARED_SYMBOL_TABLE;
+
+ if (IERR_OK != ion_symbol_table_open_with_type(&g_sym_tab_php, NULL, ist_SHARED)) {
+ return FAILURE;
+ }
+ 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.value);
+ while (ptr->e.value) {
+ 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);
+ 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
+}
+