]> granicus.if.org Git - php/commitdiff
Refactored sqlite3 (all tests passes)
authorXinchen Hui <laruence@gmail.com>
Tue, 22 Apr 2014 16:17:29 +0000 (00:17 +0800)
committerXinchen Hui <laruence@gmail.com>
Tue, 22 Apr 2014 16:17:29 +0000 (00:17 +0800)
ext/sqlite3/php_sqlite3_structs.h
ext/sqlite3/sqlite3.c

index 5336d116fc03a3bc86ae9bf5f8d3dc700927d38a..dd81317df26a6d7a020b655f22b25b56b28fc98b 100644 (file)
@@ -43,7 +43,7 @@ struct php_sqlite3_bound_param  {
        int name_len;
        long type;
 
-       zval *parameter;
+       zval parameter;
 };
 
 struct php_sqlite3_fci {
@@ -58,7 +58,7 @@ typedef struct _php_sqlite3_func {
        const char *func_name;
        int argc;
 
-       zval *func, *step, *fini;
+       zval func, step, fini;
        struct php_sqlite3_fci afunc, astep, afini;
 } php_sqlite3_func;
 
@@ -67,13 +67,12 @@ typedef struct _php_sqlite3_collation {
        struct _php_sqlite3_collation *next;
 
        const char *collation_name;
-       zval *cmp_func;
+       zval cmp_func;
        struct php_sqlite3_fci fci;
 } php_sqlite3_collation;
 
 /* Structure for SQLite Database object. */
 typedef struct _php_sqlite3_db_object  {
-       zend_object zo;
        int initialised;
        sqlite3 *db;
        php_sqlite3_func *funcs;
@@ -82,11 +81,18 @@ typedef struct _php_sqlite3_db_object  {
        zend_bool exception;
 
        zend_llist free_list;
+       zend_object zo;
 } php_sqlite3_db_object;
 
+static inline php_sqlite3_db_object *php_sqlite3_db_from_obj(zend_object *obj) {
+       return (php_sqlite3_db_object*)((char*)(obj) - XtOffsetOf(php_sqlite3_db_object, zo));
+}
+
+#define Z_SQLITE3_DB_P(zv)  php_sqlite3_db_from_obj(Z_OBJ_P((zv)))
+
 /* Structure for SQLite Database object. */
 typedef struct _php_sqlite3_agg_context  {
-       zval *zval_context;
+       zval zval_context;
        long row_count;
 } php_sqlite3_agg_context;
 
@@ -95,34 +101,46 @@ typedef struct _php_sqlite3_result_object php_sqlite3_result;
 
 /* sqlite3 objects to be destroyed */
 typedef struct _php_sqlite3_free_list {
-       zval *stmt_obj_zval;
+       zval stmt_obj_zval;
        php_sqlite3_stmt *stmt_obj;
 } php_sqlite3_free_list;
 
 /* Structure for SQLite Result object. */
 struct _php_sqlite3_result_object  {
-       zend_object zo;
        php_sqlite3_db_object *db_obj;
        php_sqlite3_stmt *stmt_obj;
-       zval *stmt_obj_zval;
+       zval stmt_obj_zval;
        
        int is_prepared_statement;
        int complete;
+       zend_object zo;
 };
 
+static inline php_sqlite3_result *php_sqlite3_result_from_obj(zend_object *obj) {
+       return (php_sqlite3_result*)((char*)(obj) - XtOffsetOf(php_sqlite3_result, zo));
+}
+
+#define Z_SQLITE3_RESULT_P(zv)  php_sqlite3_result_from_obj(Z_OBJ_P((zv)))
+
 /* Structure for SQLite Statement object. */
 struct _php_sqlite3_stmt_object  {
-       zend_object zo;
        sqlite3_stmt *stmt;
        php_sqlite3_db_object *db_obj;
-       zval *db_obj_zval;
+       zval db_obj_zval;
 
        int initialised;
 
        /* Keep track of the zvals for bound parameters */
        HashTable *bound_params;
+       zend_object zo;
 };
 
+static inline php_sqlite3_stmt *php_sqlite3_stmt_from_obj(zend_object *obj) {
+       return (php_sqlite3_stmt*)((char*)(obj) - XtOffsetOf(php_sqlite3_stmt, zo));
+}
+
+#define Z_SQLITE3_STMT_P(zv)  php_sqlite3_stmt_from_obj(Z_OBJ_P((zv)))
+
 #endif
 
 
index ef857d4f412b1d29c10956f42e026cecce633229..10d1694658ef48814ad53e546cf41f455ed4faf1 100644 (file)
@@ -39,7 +39,7 @@ ZEND_DECLARE_MODULE_GLOBALS(sqlite3)
 
 static PHP_GINIT_FUNCTION(sqlite3);
 static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6);
-static void sqlite3_param_dtor(void *data);
+static void sqlite3_param_dtor(zval *data);
 static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
 
 /* {{{ Error Handler
@@ -100,7 +100,7 @@ PHP_METHOD(sqlite3, open)
        long flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
        zend_error_handling error_handling;
 
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
        zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
 
        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ls", &filename, &filename_len, &flags, &encryption_key, &encryption_key_len)) {
@@ -184,7 +184,7 @@ PHP_METHOD(sqlite3, close)
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
        int errcode;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -212,7 +212,7 @@ PHP_METHOD(sqlite3, exec)
        zval *object = getThis();
        char *sql, *errtext = NULL;
        int sql_len;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -253,7 +253,7 @@ PHP_METHOD(sqlite3, lastInsertRowID)
 {
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -271,7 +271,7 @@ PHP_METHOD(sqlite3, lastErrorCode)
 {
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
 
@@ -289,7 +289,7 @@ PHP_METHOD(sqlite3, lastErrorMsg)
 {
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
 
@@ -297,7 +297,7 @@ PHP_METHOD(sqlite3, lastErrorMsg)
                return;
        }
 
-       RETVAL_STRING((char *)sqlite3_errmsg(db_obj->db), 1);
+       RETVAL_STRING((char *)sqlite3_errmsg(db_obj->db));
 }
 /* }}} */
 
@@ -309,7 +309,7 @@ PHP_METHOD(sqlite3, busyTimeout)
        zval *object = getThis();
        long ms;
        int return_code;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -338,7 +338,7 @@ PHP_METHOD(sqlite3, loadExtension)
        char *extension, *lib_path, *extension_dir, *errtext = NULL;
        char fullpath[MAXPATHLEN];
        int extension_len, extension_dir_len;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -408,7 +408,7 @@ PHP_METHOD(sqlite3, changes)
 {
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -434,7 +434,7 @@ PHP_METHOD(sqlite3, escapeString)
        if (sql_len) {
                ret = sqlite3_mprintf("%q", sql);
                if (ret) {
-                       RETVAL_STRING(ret, 1);
+                       RETVAL_STRING(ret);
                        sqlite3_free(ret);
                }
        } else {
@@ -454,7 +454,7 @@ PHP_METHOD(sqlite3, prepare)
        int sql_len, errcode;
        php_sqlite3_free_list *free_item;
 
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -467,11 +467,9 @@ PHP_METHOD(sqlite3, prepare)
        }
 
        object_init_ex(return_value, php_sqlite3_stmt_entry);
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(return_value TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(return_value);
        stmt_obj->db_obj = db_obj;
-       stmt_obj->db_obj_zval = getThis();
-
-       Z_ADDREF_P(object);
+       ZVAL_COPY(&stmt_obj->db_obj_zval, object);
 
        errcode = sqlite3_prepare_v2(db_obj->db, sql, sql_len, &(stmt_obj->stmt), NULL);
        if (errcode != SQLITE_OK) {
@@ -484,7 +482,7 @@ PHP_METHOD(sqlite3, prepare)
 
        free_item = emalloc(sizeof(php_sqlite3_free_list));
        free_item->stmt_obj = stmt_obj;
-       free_item->stmt_obj_zval = return_value;
+       ZVAL_COPY_VALUE(&free_item->stmt_obj_zval, return_value);
 
        zend_llist_add_element(&(db_obj->free_list), &free_item);
 }
@@ -498,10 +496,10 @@ PHP_METHOD(sqlite3, query)
        php_sqlite3_result *result;
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
-       zval *stmt = NULL;
+       zval stmt;
        char *sql, *errtext = NULL;
        int sql_len, return_code;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -514,7 +512,7 @@ PHP_METHOD(sqlite3, query)
        }
 
        /* If there was no return value then just execute the query */
-       if (!return_value_used) {
+       if (!USED_RET()) {
                if (sqlite3_exec(db_obj->db, sql, NULL, NULL, &errtext) != SQLITE_OK) {
                        php_sqlite3_error(db_obj, "%s", errtext);
                        sqlite3_free(errtext);
@@ -522,14 +520,10 @@ PHP_METHOD(sqlite3, query)
                return;
        }
 
-       MAKE_STD_ZVAL(stmt);
-
-       object_init_ex(stmt, php_sqlite3_stmt_entry);
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(stmt TSRMLS_CC);
+       object_init_ex(&stmt, php_sqlite3_stmt_entry);
+       stmt_obj = Z_SQLITE3_STMT_P(&stmt);
        stmt_obj->db_obj = db_obj;
-       stmt_obj->db_obj_zval = getThis();
-
-       Z_ADDREF_P(object);
+       ZVAL_COPY(&stmt_obj->db_obj_zval, object);
 
        return_code = sqlite3_prepare_v2(db_obj->db, sql, sql_len, &(stmt_obj->stmt), NULL);
        if (return_code != SQLITE_OK) {
@@ -541,10 +535,10 @@ PHP_METHOD(sqlite3, query)
        stmt_obj->initialised = 1;
 
        object_init_ex(return_value, php_sqlite3_result_entry);
-       result = (php_sqlite3_result *)zend_object_store_get_object(return_value TSRMLS_CC);
+       result = Z_SQLITE3_RESULT_P(return_value TSRMLS_CC);
        result->db_obj = db_obj;
        result->stmt_obj = stmt_obj;
-       result->stmt_obj_zval = stmt;
+       ZVAL_COPY_VALUE(&result->stmt_obj_zval, &stmt);
 
        return_code = sqlite3_step(result->stmt_obj->stmt);
 
@@ -570,14 +564,12 @@ PHP_METHOD(sqlite3, query)
 }
 /* }}} */
 
-static zval* sqlite_value_to_zval(sqlite3_stmt *stmt, int column) /* {{{ */
+static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* {{{ */
 {
-       zval *data;
-       MAKE_STD_ZVAL(data);
        switch (sqlite3_column_type(stmt, column)) {
                case SQLITE_INTEGER:
                        if ((sqlite3_column_int64(stmt, column)) >= INT_MAX || sqlite3_column_int64(stmt, column) <= INT_MIN) {
-                               ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column), 1);
+                               ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column));
                        } else {
                                ZVAL_LONG(data, sqlite3_column_int64(stmt, column));
                        }
@@ -592,14 +584,13 @@ static zval* sqlite_value_to_zval(sqlite3_stmt *stmt, int column) /* {{{ */
                        break;
 
                case SQLITE3_TEXT:
-                       ZVAL_STRING(data, (char*)sqlite3_column_text(stmt, column), 1);
+                       ZVAL_STRING(data, (char*)sqlite3_column_text(stmt, column));
                        break;
 
                case SQLITE_BLOB:
                default:
-                       ZVAL_STRINGL(data, (char*)sqlite3_column_blob(stmt, column), sqlite3_column_bytes(stmt, column), 1);
+                       ZVAL_STRINGL(data, (char*)sqlite3_column_blob(stmt, column), sqlite3_column_bytes(stmt, column));
        }
-       return data;
 }
 /* }}} */
 
@@ -613,7 +604,7 @@ PHP_METHOD(sqlite3, querySingle)
        int sql_len, return_code;
        zend_bool entire_row = 0;
        sqlite3_stmt *stmt;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -626,7 +617,7 @@ PHP_METHOD(sqlite3, querySingle)
        }
 
        /* If there was no return value then just execute the query */
-       if (!return_value_used) {
+       if (!USED_RET()) {
                if (sqlite3_exec(db_obj->db, sql, NULL, NULL, &errtext) != SQLITE_OK) {
                        php_sqlite3_error(db_obj, "%s", errtext);
                        sqlite3_free(errtext);
@@ -646,19 +637,14 @@ PHP_METHOD(sqlite3, querySingle)
                case SQLITE_ROW: /* Valid Row */
                {
                        if (!entire_row) {
-                               zval *data;
-                               data = sqlite_value_to_zval(stmt, 0);
-                               *return_value = *data;
-                               zval_copy_ctor(return_value);
-                               zval_dtor(data);
-                               FREE_ZVAL(data);
+                               sqlite_value_to_zval(stmt, 0, return_value);
                        } else {
                                int i = 0;
                                array_init(return_value);
                                for (i = 0; i < sqlite3_data_count(stmt); i++) {
-                                       zval *data;
-                                       data = sqlite_value_to_zval(stmt, i);
-                                       add_assoc_zval(return_value, (char*)sqlite3_column_name(stmt, i), data);
+                                       zval data;
+                                       sqlite_value_to_zval(stmt, i, &data);
+                                       add_assoc_zval(return_value, (char*)sqlite3_column_name(stmt, i), &data);
                                }
                        }
                        break;
@@ -682,8 +668,8 @@ PHP_METHOD(sqlite3, querySingle)
 
 static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, sqlite3_value **argv, sqlite3_context *context, int is_agg TSRMLS_DC) /* {{{ */
 {
-       zval ***zargs = NULL;
-       zval *retval = NULL;
+       zval *zargs = NULL;
+       zval retval;
        int i;
        int ret;
        int fake_argc;
@@ -697,58 +683,51 @@ static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, s
 
        fc->fci.size = sizeof(fc->fci);
        fc->fci.function_table = EG(function_table);
-       fc->fci.function_name = cb;
+       ZVAL_COPY_VALUE(&fc->fci.function_name, cb);
        fc->fci.symbol_table = NULL;
-       fc->fci.object_ptr = NULL;
-       fc->fci.retval_ptr_ptr = &retval;
+       fc->fci.object = NULL;
+       fc->fci.retval = &retval;
        fc->fci.param_count = fake_argc;
 
        /* build up the params */
 
        if (fake_argc) {
-               zargs = (zval ***)safe_emalloc(fake_argc, sizeof(zval **), 0);
+               zargs = (zval *)safe_emalloc(fake_argc, sizeof(zval), 0);
        }
 
        if (is_agg) {
                /* summon the aggregation context */
                agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
 
-               if (!agg_context->zval_context) {
-                       MAKE_STD_ZVAL(agg_context->zval_context);
-                       ZVAL_NULL(agg_context->zval_context);
+               if (ZVAL_IS_UNDEF(&agg_context->zval_context)) {
+                       ZVAL_NULL(&agg_context->zval_context);
                }
-               zargs[0] = &agg_context->zval_context;
-
-               zargs[1] = emalloc(sizeof(zval*));
-               MAKE_STD_ZVAL(*zargs[1]);
-               ZVAL_LONG(*zargs[1], agg_context->row_count);
+               ZVAL_COPY_VALUE(&zargs[0], &agg_context->zval_context);
+               ZVAL_LONG(&zargs[1], agg_context->row_count);
        }
 
        for (i = 0; i < argc; i++) {
-               zargs[i + is_agg] = emalloc(sizeof(zval *));
-               MAKE_STD_ZVAL(*zargs[i + is_agg]);
-
                switch (sqlite3_value_type(argv[i])) {
                        case SQLITE_INTEGER:
 #if LONG_MAX > 2147483647
-                               ZVAL_LONG(*zargs[i + is_agg], sqlite3_value_int64(argv[i]));
+                               ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int64(argv[i]));
 #else
-                               ZVAL_LONG(*zargs[i + is_agg], sqlite3_value_int(argv[i]));
+                               ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
 #endif
                                break;
 
                        case SQLITE_FLOAT:
-                               ZVAL_DOUBLE(*zargs[i + is_agg], sqlite3_value_double(argv[i]));
+                               ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i]));
                                break;
 
                        case SQLITE_NULL:
-                               ZVAL_NULL(*zargs[i + is_agg]);
+                               ZVAL_NULL(&zargs[i + is_agg]);
                                break;
 
                        case SQLITE_BLOB:
                        case SQLITE3_TEXT:
                        default:
-                               ZVAL_STRINGL(*zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]), 1);
+                               ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]));
                                break;
                }
        }
@@ -762,12 +741,10 @@ static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, s
        /* clean up the params */
        if (fake_argc) {
                for (i = is_agg; i < argc + is_agg; i++) {
-                       zval_ptr_dtor(zargs[i]);
-                       efree(zargs[i]);
+                       zval_ptr_dtor(&zargs[i]);
                }
                if (is_agg) {
-                       zval_ptr_dtor(zargs[1]);
-                       efree(zargs[1]);
+                       zval_ptr_dtor(&zargs[1]);
                }
                efree(zargs);
        }
@@ -775,13 +752,13 @@ static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, s
        if (!is_agg || !argv) {
                /* only set the sqlite return value if we are a scalar function,
                 * or if we are finalizing an aggregate */
-               if (retval) {
-                       switch (Z_TYPE_P(retval)) {
+               if (!ZVAL_IS_UNDEF(&retval)) {
+                       switch (Z_TYPE(retval)) {
                                case IS_LONG:
 #if LONG_MAX > 2147483647
-                                       sqlite3_result_int64(context, Z_LVAL_P(retval));
+                                       sqlite3_result_int64(context, Z_LVAL(retval));
 #else
-                                       sqlite3_result_int(context, Z_LVAL_P(retval));
+                                       sqlite3_result_int(context, Z_LVAL(retval));
 #endif
                                        break;
 
@@ -790,36 +767,32 @@ static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, s
                                        break;
 
                                case IS_DOUBLE:
-                                       sqlite3_result_double(context, Z_DVAL_P(retval));
+                                       sqlite3_result_double(context, Z_DVAL(retval));
                                        break;
 
                                default:
                                        convert_to_string_ex(&retval);
-                                       sqlite3_result_text(context, Z_STRVAL_P(retval), Z_STRLEN_P(retval), SQLITE_TRANSIENT);
+                                       sqlite3_result_text(context, Z_STRVAL(retval), Z_STRLEN(retval), SQLITE_TRANSIENT);
                                        break;
                        }
                } else {
                        sqlite3_result_error(context, "failed to invoke callback", 0);
                }
 
-               if (agg_context && agg_context->zval_context) {
+               if (agg_context && !ZVAL_IS_UNDEF(&agg_context->zval_context)) {
                        zval_ptr_dtor(&agg_context->zval_context);
                }
        } else {
                /* we're stepping in an aggregate; the return value goes into
                 * the context */
-               if (agg_context && agg_context->zval_context) {
+               if (agg_context && !ZVAL_IS_UNDEF(&agg_context->zval_context)) {
                        zval_ptr_dtor(&agg_context->zval_context);
                }
-               if (retval) {
-                       agg_context->zval_context = retval;
-                       retval = NULL;
-               } else {
-                       agg_context->zval_context = NULL;
-               }
+               ZVAL_COPY_VALUE(&agg_context->zval_context, &retval);
+               ZVAL_UNDEF(&retval);
        }
 
-       if (retval) {
+       if (!ZVAL_IS_UNDEF(&retval)) {
                zval_ptr_dtor(&retval);
        }
        return ret;
@@ -831,7 +804,7 @@ static void php_sqlite3_callback_func(sqlite3_context *context, int argc, sqlite
        php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
        TSRMLS_FETCH();
 
-       sqlite3_do_callback(&func->afunc, func->func, argc, argv, context, 0 TSRMLS_CC);
+       sqlite3_do_callback(&func->afunc, &func->func, argc, argv, context, 0 TSRMLS_CC);
 }
 /* }}}*/
 
@@ -843,7 +816,7 @@ static void php_sqlite3_callback_step(sqlite3_context *context, int argc, sqlite
        TSRMLS_FETCH();
        agg_context->row_count++;
 
-       sqlite3_do_callback(&func->astep, func->step, argc, argv, context, 1 TSRMLS_CC);
+       sqlite3_do_callback(&func->astep, &func->step, argc, argv, context, 1 TSRMLS_CC);
 }
 /* }}} */
 
@@ -855,36 +828,30 @@ static void php_sqlite3_callback_final(sqlite3_context *context) /* {{{ */
        TSRMLS_FETCH();
        agg_context->row_count = 0;
 
-       sqlite3_do_callback(&func->afini, func->fini, 0, NULL, context, 1 TSRMLS_CC);
+       sqlite3_do_callback(&func->afini, &func->fini, 0, NULL, context, 1 TSRMLS_CC);
 }
 /* }}} */
 
 static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, int b_len, const void* b) /* {{{ */
 {
        php_sqlite3_collation *collation = (php_sqlite3_collation*)coll;
-       zval ***zargs = NULL;
-       zval *retval = NULL;
+       zval *zargs = NULL;
+       zval retval;
        int ret;
 
        TSRMLS_FETCH();
 
        collation->fci.fci.size = (sizeof(collation->fci.fci));
        collation->fci.fci.function_table = EG(function_table);
-       collation->fci.fci.function_name = collation->cmp_func;
+       ZVAL_COPY_VALUE(&collation->fci.fci.function_name, &collation->cmp_func);
        collation->fci.fci.symbol_table = NULL;
-       collation->fci.fci.object_ptr = NULL;
-       collation->fci.fci.retval_ptr_ptr = &retval;
+       collation->fci.fci.object = NULL;
+       collation->fci.fci.retval = &retval;
        collation->fci.fci.param_count = 2;
 
-       zargs = (zval***)safe_emalloc(2, sizeof(zval**), 0);
-       zargs[0] = emalloc(sizeof(zval*));
-       zargs[1] = emalloc(sizeof(zval*));
-
-       MAKE_STD_ZVAL(*zargs[0]);
-       ZVAL_STRINGL(*zargs[0], a, a_len, 1);
-
-       MAKE_STD_ZVAL(*zargs[1]);
-       ZVAL_STRINGL(*zargs[1], b, b_len, 1);
+       zargs = safe_emalloc(2, sizeof(zval), 0);
+       ZVAL_STRINGL(&zargs[0], a, a_len);
+       ZVAL_STRINGL(&zargs[1], b, b_len);
  
        collation->fci.fci.params = zargs;
 
@@ -892,19 +859,17 @@ static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, in
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the compare callback");
        }
 
-       zval_ptr_dtor(zargs[0]);
-       zval_ptr_dtor(zargs[1]);
-       efree(zargs[0]);
-       efree(zargs[1]);
+       zval_ptr_dtor(&zargs[0]);
+       zval_ptr_dtor(&zargs[1]);
        efree(zargs);
 
        //retval ought to contain a ZVAL_LONG by now
        // (the result of a comparison, i.e. most likely -1, 0, or 1)
        //I suppose we could accept any scalar return type, though.
-       if (Z_TYPE_P(retval) != IS_LONG){
+       if (Z_TYPE(retval) != IS_LONG){
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the compare callback (invalid return type).  Collation behaviour is undefined.");
        }else{
-               ret = Z_LVAL_P(retval);
+               ret = Z_LVAL(retval);
        }
 
        zval_ptr_dtor(&retval);
@@ -920,11 +885,12 @@ PHP_METHOD(sqlite3, createFunction)
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
        php_sqlite3_func *func;
-       char *sql_func, *callback_name;
+       char *sql_func;
        int sql_func_len;
        zval *callback_func;
+       zend_string *callback_name;
        long sql_func_num_args = -1;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -937,19 +903,18 @@ PHP_METHOD(sqlite3, createFunction)
        }
 
        if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
-               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name);
-               efree(callback_name);
+               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name->val);
+               STR_RELEASE(callback_name);
                RETURN_FALSE;
        }
-       efree(callback_name);
+       STR_RELEASE(callback_name);
 
        func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
 
        if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
                func->func_name = estrdup(sql_func);
 
-               MAKE_STD_ZVAL(func->func);
-               MAKE_COPY_ZVAL(&callback_func, func->func);
+               ZVAL_COPY(&func->func, callback_func);
 
                func->argc = sql_func_num_args;
                func->next = db_obj->funcs;
@@ -970,11 +935,12 @@ PHP_METHOD(sqlite3, createAggregate)
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
        php_sqlite3_func *func;
-       char *sql_func, *callback_name;
+       char *sql_func;
+       zend_string *callback_name;
        int sql_func_len;
        zval *step_callback, *fini_callback;
        long sql_func_num_args = -1;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -987,29 +953,26 @@ PHP_METHOD(sqlite3, createAggregate)
        }
 
        if (!zend_is_callable(step_callback, 0, &callback_name TSRMLS_CC)) {
-               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name);
-               efree(callback_name);
+               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name->val);
+               STR_RELEASE(callback_name);
                RETURN_FALSE;
        }
-       efree(callback_name);
+       STR_RELEASE(callback_name);
 
        if (!zend_is_callable(fini_callback, 0, &callback_name TSRMLS_CC)) {
-               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name);
-               efree(callback_name);
+               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name->val);
+               STR_RELEASE(callback_name);
                RETURN_FALSE;
        }
-       efree(callback_name);
+       STR_RELEASE(callback_name);
 
        func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
 
        if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) {
                func->func_name = estrdup(sql_func);
 
-               MAKE_STD_ZVAL(func->step);
-               MAKE_COPY_ZVAL(&step_callback, func->step);
-
-               MAKE_STD_ZVAL(func->fini);
-               MAKE_COPY_ZVAL(&fini_callback, func->fini);
+               ZVAL_COPY(&func->step, step_callback);
+               ZVAL_COPY(&func->fini, fini_callback);
 
                func->argc = sql_func_num_args;
                func->next = db_obj->funcs;
@@ -1030,10 +993,11 @@ PHP_METHOD(sqlite3, createCollation)
        php_sqlite3_db_object *db_obj;
        zval *object = getThis();
        php_sqlite3_collation *collation;
-       char *collation_name, *callback_name;
+       char *collation_name;
+       zend_string *callback_name;
        int collation_name_len;
        zval *callback_func;
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -1046,18 +1010,17 @@ PHP_METHOD(sqlite3, createCollation)
        }
 
        if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
-               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name);
-               efree(callback_name);
+               php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name->val);
+               STR_RELEASE(callback_name);
                RETURN_FALSE;
        }
-       efree(callback_name);
+       STR_RELEASE(callback_name);
 
        collation = (php_sqlite3_collation *)ecalloc(1, sizeof(*collation));
        if (sqlite3_create_collation(db_obj->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_callback_compare) == SQLITE_OK) {
                collation->collation_name = estrdup(collation_name);
 
-               MAKE_STD_ZVAL(collation->cmp_func);
-               MAKE_COPY_ZVAL(&callback_func, collation->cmp_func);
+               ZVAL_COPY(&collation->cmp_func, callback_func);
 
                collation->next = db_obj->collations;
                db_obj->collations = collation;
@@ -1219,7 +1182,7 @@ PHP_METHOD(sqlite3, openBlob)
        php_stream_sqlite3_data *sqlite3_stream;
        php_stream *stream;
 
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -1255,7 +1218,7 @@ PHP_METHOD(sqlite3, enableExceptions)
        zval *object = getThis();
        zend_bool enableExceptions = 0;
 
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(object);
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enableExceptions) == FAILURE) {
                return;
@@ -1273,7 +1236,7 @@ PHP_METHOD(sqlite3stmt, paramCount)
 {
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1289,7 +1252,7 @@ PHP_METHOD(sqlite3stmt, close)
 {
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1307,7 +1270,7 @@ PHP_METHOD(sqlite3stmt, reset)
 {
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1327,7 +1290,7 @@ PHP_METHOD(sqlite3stmt, clear)
 {
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1348,7 +1311,7 @@ PHP_METHOD(sqlite3stmt, readOnly)
 {
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1399,9 +1362,9 @@ static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *pa
        }
 
        if (param->name) {
-               zend_hash_update(hash, param->name, param->name_len, param, sizeof(*param), NULL);
+               zend_hash_str_update_mem(hash, param->name, param->name_len, param, sizeof(struct php_sqlite3_bound_param));
        } else {
-               zend_hash_index_update(hash, param->param_number, param, sizeof(*param), NULL);
+               zend_hash_index_update_mem(hash, param->param_number, param, sizeof(struct php_sqlite3_bound_param));
        }
 
        return 1;
@@ -1415,23 +1378,24 @@ PHP_METHOD(sqlite3stmt, bindParam)
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
        struct php_sqlite3_bound_param param = {0};
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
+       zval *parameter;
 
        param.param_number = -1;
        param.type = SQLITE3_TEXT;
 
-       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz|l", &param.param_number, &param.parameter, &param.type) == FAILURE) {
-               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &param.name, &param.name_len, &param.parameter, &param.type) == FAILURE) {
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz|l", &param.param_number, &parameter, &param.type) == FAILURE) {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &param.name, &param.name_len, &parameter, &param.type) == FAILURE) {
                        return;
                }
        }
 
-       Z_ADDREF_P(param.parameter);
+       ZVAL_COPY(&param.parameter, parameter);
 
        if (!register_bound_parameter_to_sqlite(&param, stmt_obj TSRMLS_CC)) {
-               if (param.parameter) {
+               if (!ZVAL_IS_UNDEF(&param.parameter)) {
                        zval_ptr_dtor(&(param.parameter));
-                       param.parameter = NULL;
+                       ZVAL_UNDEF(&param.parameter);
                }
                RETURN_FALSE;
        }
@@ -1446,23 +1410,24 @@ PHP_METHOD(sqlite3stmt, bindValue)
        php_sqlite3_stmt *stmt_obj;
        zval *object = getThis();
        struct php_sqlite3_bound_param param = {0};
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
+       zval *parameter;
 
        param.param_number = -1;
        param.type = SQLITE3_TEXT;
 
-       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz/|l", &param.param_number, &param.parameter, &param.type) == FAILURE) {
-               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|l", &param.name, &param.name_len, &param.parameter, &param.type) == FAILURE) {
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz/|l", &param.param_number, &parameter, &param.type) == FAILURE) {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|l", &param.name, &param.name_len, &parameter, &param.type) == FAILURE) {
                        return;
                }
        }
 
-       Z_ADDREF_P(param.parameter);
+       ZVAL_COPY(&param.parameter, parameter);
 
        if (!register_bound_parameter_to_sqlite(&param, stmt_obj TSRMLS_CC)) {
-               if (param.parameter) {
+               if (!ZVAL_IS_UNDEF(&param.parameter)) {
                        zval_ptr_dtor(&(param.parameter));
-                       param.parameter = NULL;
+                       ZVAL_UNDEF(&param.parameter);
                }
                RETURN_FALSE;
        }
@@ -1480,7 +1445,7 @@ PHP_METHOD(sqlite3stmt, execute)
        int return_code = 0;
        struct php_sqlite3_bound_param *param;
 
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1489,59 +1454,62 @@ PHP_METHOD(sqlite3stmt, execute)
        SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3)
 
        if (stmt_obj->bound_params) {
-               zend_hash_internal_pointer_reset(stmt_obj->bound_params);
-               while (zend_hash_get_current_data(stmt_obj->bound_params, (void **)&param) == SUCCESS) {
+               ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) {
+                       zval parameter;
+                       ZVAL_COPY_VALUE(&parameter, &param->parameter);
+
+                       if (Z_ISREF_P(&parameter)) {
+                               ZVAL_DUP(&parameter, Z_REFVAL(parameter));
+                       }
+
                        /* If the ZVAL is null then it should be bound as that */
-                       if (Z_TYPE_P(param->parameter) == IS_NULL) {
+                       if (Z_TYPE(parameter) == IS_NULL) {
                                sqlite3_bind_null(stmt_obj->stmt, param->param_number);
-                               zend_hash_move_forward(stmt_obj->bound_params);
                                continue;
                        }
 
                        switch (param->type) {
                                case SQLITE_INTEGER:
-                                       convert_to_long(param->parameter);
+                                       convert_to_long(&parameter);
 #if LONG_MAX > 2147483647
-                                       sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(param->parameter));
+                                       sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL(parameter));
 #else
-                                       sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(param->parameter));
+                                       sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL(parameter));
 #endif
                                        break;
 
                                case SQLITE_FLOAT:
-                                       /* convert_to_double(param->parameter);*/
-                                       sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(param->parameter));
+                                       /* convert_to_double(parameter);*/
+                                       sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL(parameter));
                                        break;
 
                                case SQLITE_BLOB:
                                {
                                        php_stream *stream = NULL;
-                                       int blength;
-                                       char *buffer = NULL;
-                                       if (Z_TYPE_P(param->parameter) == IS_RESOURCE) {
-                                               php_stream_from_zval_no_verify(stream, &param->parameter);
+                                       zend_string *buffer;
+                                       if (Z_TYPE(parameter) == IS_RESOURCE) {
+                                               php_stream_from_zval_no_verify(stream, &parameter);
                                                if (stream == NULL) {
                                                        php_sqlite3_error(stmt_obj->db_obj, "Unable to read stream for parameter %ld", param->param_number);
                                                        RETURN_FALSE;
                                                }
-                                               blength = php_stream_copy_to_mem(stream, (void *)&buffer, PHP_STREAM_COPY_ALL, 0);
+                                               buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
                                        } else {
-                                               convert_to_string(param->parameter);
-                                               blength =  Z_STRLEN_P(param->parameter);
-                                               buffer = Z_STRVAL_P(param->parameter);
+                                               convert_to_string(&parameter);
+                                               buffer = Z_STR(parameter);
                                        }
 
-                                       sqlite3_bind_blob(stmt_obj->stmt, param->param_number, buffer, blength, SQLITE_TRANSIENT);
+                                       sqlite3_bind_blob(stmt_obj->stmt, param->param_number, buffer->val, buffer->len, SQLITE_TRANSIENT);
 
                                        if (stream) {
-                                               pefree(buffer, 0);
+                                               STR_RELEASE(buffer);
                                        }
                                        break;
                                }
 
                                case SQLITE3_TEXT:
-                                       convert_to_string(param->parameter);
-                                       sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter), SQLITE_STATIC);
+                                       convert_to_string(&parameter);
+                                       sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL(parameter), Z_STRLEN(parameter), SQLITE_STATIC);
                                        break;
 
                                case SQLITE_NULL:
@@ -1552,8 +1520,7 @@ PHP_METHOD(sqlite3stmt, execute)
                                        php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %ld for parameter %ld", param->type, param->param_number);
                                        RETURN_FALSE;
                        }
-                       zend_hash_move_forward(stmt_obj->bound_params);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        return_code = sqlite3_step(stmt_obj->stmt);
@@ -1564,14 +1531,12 @@ PHP_METHOD(sqlite3stmt, execute)
                {
                        sqlite3_reset(stmt_obj->stmt);
                        object_init_ex(return_value, php_sqlite3_result_entry);
-                       result = (php_sqlite3_result *)zend_object_store_get_object(return_value TSRMLS_CC);
+                       result = Z_SQLITE3_RESULT_P(return_value TSRMLS_CC);
 
-                       Z_ADDREF_P(object);
-       
                        result->is_prepared_statement = 1;
                        result->db_obj = stmt_obj->db_obj;
                        result->stmt_obj = stmt_obj;
-                       result->stmt_obj_zval = getThis();
+                       ZVAL_COPY(&result->stmt_obj_zval, object);
 
                        break;
                }
@@ -1601,7 +1566,7 @@ PHP_METHOD(sqlite3stmt, __construct)
        zend_error_handling error_handling;
        php_sqlite3_free_list *free_item;
 
-       stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC);
+       stmt_obj = Z_SQLITE3_STMT_P(object);
        zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &db_zval, php_sqlite3_sc_entry, &sql, &sql_len) == FAILURE) {
@@ -1609,7 +1574,7 @@ PHP_METHOD(sqlite3stmt, __construct)
                return;
        }
 
-       db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(db_zval TSRMLS_CC);
+       db_obj = Z_SQLITE3_DB_P(db_zval);
 
        SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
@@ -1620,9 +1585,7 @@ PHP_METHOD(sqlite3stmt, __construct)
        }
 
        stmt_obj->db_obj = db_obj;
-       stmt_obj->db_obj_zval = db_zval;
-
-       Z_ADDREF_P(db_zval);
+       ZVAL_COPY(&stmt_obj->db_obj_zval, db_zval);
        
        errcode = sqlite3_prepare_v2(db_obj->db, sql, sql_len, &(stmt_obj->stmt), NULL);
        if (errcode != SQLITE_OK) {
@@ -1634,7 +1597,8 @@ PHP_METHOD(sqlite3stmt, __construct)
 
        free_item = emalloc(sizeof(php_sqlite3_free_list));
        free_item->stmt_obj = stmt_obj;
-       free_item->stmt_obj_zval = getThis();
+       //??  free_item->stmt_obj_zval = getThis();
+       ZVAL_COPY_VALUE(&free_item->stmt_obj_zval, object);
 
        zend_llist_add_element(&(db_obj->free_list), &free_item);
 }
@@ -1646,7 +1610,7 @@ PHP_METHOD(sqlite3result, numColumns)
 {
        php_sqlite3_result *result_obj;
        zval *object = getThis();
-       result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC);
+       result_obj = Z_SQLITE3_RESULT_P(object);
 
        SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
 
@@ -1666,7 +1630,7 @@ PHP_METHOD(sqlite3result, columnName)
        zval *object = getThis();
        long column = 0;
        char *column_name;
-       result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC);
+       result_obj = Z_SQLITE3_RESULT_P(object);
 
        SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
 
@@ -1679,7 +1643,7 @@ PHP_METHOD(sqlite3result, columnName)
                RETURN_FALSE;
        }
                
-       RETVAL_STRING(column_name, 1);
+       RETVAL_STRING(column_name);
 }
 /* }}} */
 
@@ -1690,7 +1654,7 @@ PHP_METHOD(sqlite3result, columnType)
        php_sqlite3_result *result_obj;
        zval *object = getThis();
        long column = 0;
-       result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC);
+       result_obj = Z_SQLITE3_RESULT_P(object);
 
        SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
 
@@ -1714,7 +1678,7 @@ PHP_METHOD(sqlite3result, fetchArray)
        zval *object = getThis();
        int i, ret;
        long mode = PHP_SQLITE3_BOTH;
-       result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC);
+       result_obj = Z_SQLITE3_RESULT_P(object);
 
        SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
 
@@ -1726,26 +1690,28 @@ PHP_METHOD(sqlite3result, fetchArray)
        switch (ret) {
                case SQLITE_ROW:
                        /* If there was no return value then just skip fetching */
-                       if (!return_value_used) {
+                       if (!USED_RET()) {
                                return;
                        }
 
                        array_init(return_value);
 
                        for (i = 0; i < sqlite3_data_count(result_obj->stmt_obj->stmt); i++) {
-                               zval *data;
+                               zval data;
 
-                               data = sqlite_value_to_zval(result_obj->stmt_obj->stmt, i);
+                               sqlite_value_to_zval(result_obj->stmt_obj->stmt, i, &data);
 
                                if (mode & PHP_SQLITE3_NUM) {
-                                       add_index_zval(return_value, i, data);
+                                       add_index_zval(return_value, i, &data);
                                }
 
                                if (mode & PHP_SQLITE3_ASSOC) {
                                        if (mode & PHP_SQLITE3_NUM) {
-                                               Z_ADDREF_P(data);
+                                               if (Z_REFCOUNTED(data)) {
+                                                       Z_ADDREF(data);
+                                               }
                                        }
-                                       add_assoc_zval(return_value, (char*)sqlite3_column_name(result_obj->stmt_obj->stmt, i), data);
+                                       add_assoc_zval(return_value, (char*)sqlite3_column_name(result_obj->stmt_obj->stmt, i), &data);
                                }
                        }
                        break;
@@ -1767,7 +1733,7 @@ PHP_METHOD(sqlite3result, reset)
 {
        php_sqlite3_result *result_obj;
        zval *object = getThis();
-       result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC);
+       result_obj = Z_SQLITE3_RESULT_P(object);
 
        SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
 
@@ -1791,7 +1757,7 @@ PHP_METHOD(sqlite3result, finalize)
 {
        php_sqlite3_result *result_obj;
        zval *object = getThis();
-       result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC);
+       result_obj = Z_SQLITE3_RESULT_P(object);
 
        SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
 
@@ -1801,7 +1767,7 @@ PHP_METHOD(sqlite3result, finalize)
 
        /* We need to finalize an internal statement */
        if (result_obj->is_prepared_statement == 0) {
-               zend_llist_del_element(&(result_obj->db_obj->free_list), result_obj->stmt_obj_zval,
+               zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj_zval,
                        (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
        } else {
                sqlite3_reset(result_obj->stmt_obj->stmt);
@@ -2011,9 +1977,10 @@ static void php_sqlite3_free_list_dtor(void **item)
 }
 /* }}} */
 
-static int php_sqlite3_compare_stmt_zval_free( php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */
+static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */
 {
-       return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj_zval);
+       //?????  return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj_zval);
+       return  ((*free_list)->stmt_obj->initialised && Z_PTR_P(statement) == Z_PTR((*free_list)->stmt_obj_zval));      
 }
 /* }}} */
 
@@ -2023,9 +1990,9 @@ static int php_sqlite3_compare_stmt_free( php_sqlite3_free_list **free_list, sql
 }
 /* }}} */
 
-static void php_sqlite3_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+static void php_sqlite3_object_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
-       php_sqlite3_db_object *intern = (php_sqlite3_db_object *)object;
+       php_sqlite3_db_object *intern = php_sqlite3_db_from_obj(object);
        php_sqlite3_func *func;
        php_sqlite3_collation *collation;
 
@@ -2042,13 +2009,13 @@ static void php_sqlite3_object_free_storage(void *object TSRMLS_DC) /* {{{ */
 
                efree((char*)func->func_name);
 
-               if (func->func) {
+               if (!ZVAL_IS_UNDEF(&func->func)) {
                        zval_ptr_dtor(&func->func);
                }
-               if (func->step) {
+               if (!ZVAL_IS_UNDEF(&func->step)) {
                        zval_ptr_dtor(&func->step);
                }
-               if (func->fini) {
+               if (!ZVAL_IS_UNDEF(&func->fini)) {
                        zval_ptr_dtor(&func->fini);
                }
                efree(func);
@@ -2061,7 +2028,7 @@ static void php_sqlite3_object_free_storage(void *object TSRMLS_DC) /* {{{ */
                        sqlite3_create_collation(intern->db, collation->collation_name, SQLITE_UTF8, NULL, NULL);
                }
                efree((char*)collation->collation_name);
-               if (collation->cmp_func){
+               if (!ZVAL_IS_UNDEF(&collation->cmp_func)) {
                        zval_ptr_dtor(&collation->cmp_func);
                }
                efree(collation);
@@ -2073,13 +2040,12 @@ static void php_sqlite3_object_free_storage(void *object TSRMLS_DC) /* {{{ */
        }
 
        zend_object_std_dtor(&intern->zo TSRMLS_CC);
-       efree(intern);
 }
 /* }}} */
 
-static void php_sqlite3_stmt_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+static void php_sqlite3_stmt_object_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
-       php_sqlite3_stmt *intern = (php_sqlite3_stmt *)object;
+       php_sqlite3_stmt *intern = php_sqlite3_stmt_from_obj(object);
 
        if (!intern) {
                return;
@@ -2096,120 +2062,98 @@ static void php_sqlite3_stmt_object_free_storage(void *object TSRMLS_DC) /* {{{
                        (int (*)(void *, void *)) php_sqlite3_compare_stmt_free);
        }
 
-       if (intern->db_obj_zval) {
+       if (!ZVAL_IS_UNDEF(&intern->db_obj_zval)) {
                zval_ptr_dtor(&intern->db_obj_zval);
        }
 
        zend_object_std_dtor(&intern->zo TSRMLS_CC);
-       efree(intern);
 }
 /* }}} */
 
-static void php_sqlite3_result_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+static void php_sqlite3_result_object_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
-       php_sqlite3_result *intern = (php_sqlite3_result *)object;
+       php_sqlite3_result *intern = php_sqlite3_result_from_obj(object);
 
        if (!intern) {
                return;
        }
 
-       if (intern->stmt_obj_zval) {
+       if (!ZVAL_IS_NULL(&intern->stmt_obj_zval)) {
                if (intern->stmt_obj->initialised) {
                        sqlite3_reset(intern->stmt_obj->stmt);
                }
 
-               if (intern->is_prepared_statement == 0) {
-                       zval_dtor(intern->stmt_obj_zval);
-                       FREE_ZVAL(intern->stmt_obj_zval);
-               } else {
-                       zval_ptr_dtor(&intern->stmt_obj_zval);
-               }
+               zval_ptr_dtor(&intern->stmt_obj_zval);
        }
 
        zend_object_std_dtor(&intern->zo TSRMLS_CC);
-       efree(intern);
 }
 /* }}} */
 
-static zend_object_value php_sqlite3_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+static zend_object *php_sqlite3_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
-       zend_object_value retval;
        php_sqlite3_db_object *intern;
 
        /* Allocate memory for it */
-       intern = emalloc(sizeof(php_sqlite3_db_object));
-       memset(intern, 0, sizeof(php_sqlite3_db_object));
-       intern->exception = 0;
+       intern = ecalloc(1, sizeof(php_sqlite3_db_object) + sizeof(zval) * (class_type->default_properties_count - 1));
 
        /* Need to keep track of things to free */
-       zend_llist_init(&(intern->free_list),   sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);
+       zend_llist_init(&(intern->free_list),  sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);
 
        zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
        object_properties_init(&intern->zo, class_type);
 
-       retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_object_free_storage, NULL TSRMLS_CC);
-       retval.handlers = (zend_object_handlers *) &sqlite3_object_handlers;
+       intern->zo.handlers = &sqlite3_object_handlers;
 
-       return retval;
+       return &intern->zo;
 }
 /* }}} */
 
-static zend_object_value php_sqlite3_stmt_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+static zend_object *php_sqlite3_stmt_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
-       zend_object_value retval;
        php_sqlite3_stmt *intern;
 
        /* Allocate memory for it */
-       intern = emalloc(sizeof(php_sqlite3_stmt));
-       memset(intern, 0, sizeof(php_sqlite3_stmt));
-
-       intern->db_obj_zval = NULL;
+       intern = ecalloc(1, sizeof(php_sqlite3_stmt) + sizeof(zval) * (class_type->default_properties_count - 1));
 
        zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
        object_properties_init(&intern->zo, class_type);
 
-       retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_stmt_object_free_storage, NULL TSRMLS_CC);
-       retval.handlers = (zend_object_handlers *) &sqlite3_stmt_object_handlers;
+       intern->zo.handlers = &sqlite3_stmt_object_handlers;
 
-       return retval;
+       return &intern->zo;
 }
 /* }}} */
 
-static zend_object_value php_sqlite3_result_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+static zend_object *php_sqlite3_result_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
-       zend_object_value retval;
        php_sqlite3_result *intern;
 
        /* Allocate memory for it */
-       intern = emalloc(sizeof(php_sqlite3_result));
-       memset(intern, 0, sizeof(php_sqlite3_result));
-
-       intern->complete = 0;
-       intern->is_prepared_statement = 0;
-       intern->stmt_obj_zval = NULL;
+       intern = ecalloc(1, sizeof(php_sqlite3_result) + sizeof(zval) * (class_type->default_properties_count - 1));
 
        zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
        object_properties_init(&intern->zo, class_type);
 
-       retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_result_object_free_storage, NULL TSRMLS_CC);
-       retval.handlers = (zend_object_handlers *) &sqlite3_result_object_handlers;
+       intern->zo.handlers = &sqlite3_result_object_handlers;
 
-       return retval;
+       return &intern->zo;
 }
 /* }}} */
 
-static void sqlite3_param_dtor(void *data) /* {{{ */
+static void sqlite3_param_dtor(zval *data) /* {{{ */
 {
-       struct php_sqlite3_bound_param *param = (struct php_sqlite3_bound_param*)data;
+       struct php_sqlite3_bound_param *param = (struct php_sqlite3_bound_param*)Z_PTR_P(data);
 
        if (param->name) {
                efree(param->name);
        }
 
-       if (param->parameter) {
+       if (!ZVAL_IS_NULL(&param->parameter)) {
                zval_ptr_dtor(&(param->parameter));
-               param->parameter = NULL;
+               ZVAL_UNDEF(&param->parameter);
        }
+       efree(param);
 }
 /* }}} */
 
@@ -2234,19 +2178,25 @@ PHP_MINIT_FUNCTION(sqlite3)
        /* Register SQLite 3 Class */
        INIT_CLASS_ENTRY(ce, "SQLite3", php_sqlite3_class_methods);
        ce.create_object = php_sqlite3_object_new;
+       sqlite3_object_handlers.offset = XtOffsetOf(php_sqlite3_db_object, zo);
        sqlite3_object_handlers.clone_obj = NULL;
+       sqlite3_object_handlers.free_obj = php_sqlite3_object_free_storage;
        php_sqlite3_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
 
        /* Register SQLite 3 Prepared Statement Class */
        INIT_CLASS_ENTRY(ce, "SQLite3Stmt", php_sqlite3_stmt_class_methods);
        ce.create_object = php_sqlite3_stmt_object_new;
+       sqlite3_stmt_object_handlers.offset = XtOffsetOf(php_sqlite3_stmt, zo);
        sqlite3_stmt_object_handlers.clone_obj = NULL;
+       sqlite3_stmt_object_handlers.free_obj = php_sqlite3_stmt_object_free_storage;
        php_sqlite3_stmt_entry = zend_register_internal_class(&ce TSRMLS_CC);
 
        /* Register SQLite 3 Result Class */
        INIT_CLASS_ENTRY(ce, "SQLite3Result", php_sqlite3_result_class_methods);
        ce.create_object = php_sqlite3_result_object_new;
+       sqlite3_result_object_handlers.offset = XtOffsetOf(php_sqlite3_result, zo);
        sqlite3_result_object_handlers.clone_obj = NULL;
+       sqlite3_result_object_handlers.free_obj = php_sqlite3_result_object_free_storage;
        php_sqlite3_result_entry = zend_register_internal_class(&ce TSRMLS_CC);
 
        REGISTER_INI_ENTRIES();