static int32_t qb_transfer_value_from_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) { int32_t result = TRUE; if(!(ivar->flags & QB_VARIABLE_IMPORTED)) { USE_TSRM zval *zvalue = NULL, **p_zvalue = NULL; switch(scope->type) { case QB_IMPORT_SCOPE_GLOBAL: case QB_IMPORT_SCOPE_LEXICAL: { // copy value from symbol table zend_hash_quick_find(scope->symbol_table, ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &p_zvalue); } break; case QB_IMPORT_SCOPE_CLASS: { if(ivar->flags & QB_VARIABLE_CLASS_CONSTANT) { // static:: constants are treated like variables zend_class_entry *ce = scope->class_entry; zval **p_value; zend_hash_quick_find(&ce->constants_table, ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &p_value); } else { zend_class_entry *ce = scope->class_entry; p_zvalue = Z_CLASS_GET_PROP(ce, ivar->name, ivar->name_length); } } break; case QB_IMPORT_SCOPE_OBJECT: { // copy value from class instance zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC); zval *container = scope->object; p_zvalue = Z_OBJ_GET_PROP_PTR_PTR(container, name); if(!p_zvalue) { if(Z_OBJ_HT_P(container)->read_property) { zvalue = Z_OBJ_READ_PROP(container, name); } } } break; default: { } break; } if(p_zvalue) { zvalue = *p_zvalue; } if(qb_transfer_value_from_zval(scope->storage, ivar->address, (zvalue) ? zvalue : &zval_used_for_init, QB_TRANSFER_CAN_BORROW_MEMORY | QB_TRANSFER_CAN_AUTOVIVIFICATE)) { ivar->flags |= QB_VARIABLE_IMPORTED; ivar->value_pointer = p_zvalue; ivar->value = zvalue; if(!p_zvalue && zvalue) { // we got the zval from a getter function // need to up the reference count Z_ADDREF_P(zvalue); } } else { uint32_t line_id = qb_get_zend_line_id(TSRMLS_C); qb_append_exception_variable_name(ivar TSRMLS_CC); qb_set_exception_line_id(line_id TSRMLS_CC); result = FALSE; } } return result; }
static int32_t qb_transfer_value_to_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) { int32_t result = TRUE; if(ivar->flags & QB_VARIABLE_IMPORTED) { USE_TSRM zval *zvalue = ivar->value, **p_zvalue = ivar->value_pointer; if(!IS_READ_ONLY(ivar->address)) { if(zvalue) { // separate the zval first, since we're modifying it SEPARATE_ZVAL_IF_NOT_REF(&zvalue); } else { ALLOC_INIT_ZVAL(zvalue); } if(!qb_transfer_value_to_zval(scope->storage, ivar->address, zvalue)) { uint32_t line_id = qb_get_zend_line_id(TSRMLS_C); qb_append_exception_variable_name(ivar TSRMLS_CC); qb_set_exception_line_id(line_id TSRMLS_CC); result = FALSE; } if(p_zvalue) { *p_zvalue = zvalue; } else { if(ivar->flags & QB_VARIABLE_GLOBAL) { zend_hash_quick_update(&EG(symbol_table), ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &zvalue, sizeof(zval *), NULL); } else if(ivar->flags & QB_VARIABLE_CLASS_INSTANCE) { zval *container = scope->object; zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC); Z_OBJ_WRITE_PROP(container, name, zvalue); } } } if(!p_zvalue && zvalue) { // if p_zvalue isn't null, then something else has put a refcount // on the zval (and we didn't increment it earlier) zval_ptr_dtor(&zvalue); } ivar->value_pointer = NULL; ivar->value = NULL; ivar->flags &= ~QB_VARIABLE_IMPORTED; } return result; }
static int32_t qb_transfer_value_to_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) { int32_t result = TRUE; if(ivar->flags & QB_VARIABLE_IMPORTED) { USE_TSRM if(!READ_ONLY(ivar->address)) { zval *zvalue; if(ivar->value_pointer) { zvalue = *ivar->value_pointer; } else { zvalue = ivar->value; // separate the zval first, since we're modifying it SEPARATE_ZVAL_TO_MAKE_IS_REF(&zvalue); } if(!zvalue) { ALLOC_INIT_ZVAL(zvalue); if(ivar->value_pointer) { *ivar->value_pointer = zvalue; } } if(!qb_transfer_value_to_zval(scope->storage, ivar->address, zvalue)) { uint32_t line_id = qb_get_zend_line_id(TSRMLS_C); qb_set_exception_line_id(line_id TSRMLS_CC); result = FALSE; } if(!ivar->value_pointer) { if(ivar->flags & QB_VARIABLE_GLOBAL) { zend_hash_quick_update(&EG(symbol_table), ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &zvalue, sizeof(zval *), NULL); } else if(ivar->flags & QB_VARIABLE_CLASS_INSTANCE) { zval *container = scope->zend_object; zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC); Z_OBJ_WRITE_PROP(container, name, zvalue); zval_ptr_dtor(&zvalue); } } ivar->value_pointer = NULL; ivar->value = NULL; } ivar->flags &= ~QB_VARIABLE_IMPORTED; }