Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
	}